From 73ac54016446ef23ee6c5155a6009f695c6a77af Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Wed, 14 Jun 2023 22:03:17 +0100 Subject: [PATCH 01/76] Add benchmarking --- .../Toms-MacBook-Air-2.local/machine.json | 9 ++ .asv/results/benchmarks.json | 61 +++++++++++ .../Toms-MacBook-Air-2.local/machine.json | 9 ++ benchmarks/.asv/results/benchmarks.json | 41 +++++++ benchmarks/__init__.py | 0 benchmarks/asv.conf.json | 102 ++++++++++++++++++ benchmarks/kernels.py | 38 +++++++ 7 files changed, 260 insertions(+) create mode 100644 .asv/results/Toms-MacBook-Air-2.local/machine.json create mode 100644 .asv/results/benchmarks.json create mode 100644 benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json create mode 100644 benchmarks/.asv/results/benchmarks.json create mode 100644 benchmarks/__init__.py create mode 100644 benchmarks/asv.conf.json create mode 100644 benchmarks/kernels.py diff --git a/.asv/results/Toms-MacBook-Air-2.local/machine.json b/.asv/results/Toms-MacBook-Air-2.local/machine.json new file mode 100644 index 000000000..0222d4bdb --- /dev/null +++ b/.asv/results/Toms-MacBook-Air-2.local/machine.json @@ -0,0 +1,9 @@ +{ + "arch": "arm64", + "cpu": "Apple M1", + "machine": "Toms-MacBook-Air-2.local", + "num_cpu": "8", + "os": "Darwin 22.3.0", + "ram": "8589934592", + "version": 1 +} \ No newline at end of file diff --git a/.asv/results/benchmarks.json b/.asv/results/benchmarks.json new file mode 100644 index 000000000..41974721f --- /dev/null +++ b/.asv/results/benchmarks.json @@ -0,0 +1,61 @@ +{ + "kernels.MemSuite.mem_list": { + "code": "class MemSuite:\n def mem_list(self):\n return [0] * 256", + "name": "kernels.MemSuite.mem_list", + "param_names": [], + "params": [], + "timeout": 60.0, + "type": "memory", + "unit": "bytes", + "version": "abe86bab484550a681c61d7bb6eb081fbd37eb6d5009eba1df85c935530577b9" + }, + "kernels.TimeSuite.time_keys": { + "code": "class TimeSuite:\n def time_keys(self):\n for key in self.d.keys():\n pass\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", + "min_run_count": 2, + "name": "kernels.TimeSuite.time_keys", + "number": 0, + "param_names": [], + "params": [], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "86e015a3c40c52da31e4185fff7c7176c38c5e1e1e4aba71912db0b388225191", + "warmup_time": -1 + }, + "kernels.TimeSuite.time_range": { + "code": "class TimeSuite:\n def time_range(self):\n d = self.d\n for key in range(500):\n x = d[key]\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", + "min_run_count": 2, + "name": "kernels.TimeSuite.time_range", + "number": 0, + "param_names": [], + "params": [], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "cc3e85248a6284df968bcf8afe866da285261eb2487c10e9dd9e2d17a05deb47", + "warmup_time": -1 + }, + "kernels.TimeSuite.time_values": { + "code": "class TimeSuite:\n def time_values(self):\n for value in self.d.values():\n pass\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", + "min_run_count": 2, + "name": "kernels.TimeSuite.time_values", + "number": 0, + "param_names": [], + "params": [], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "cace9f2d006aa364dcf5762823afba3680c2fb50179ee30beaf880c0697256e2", + "warmup_time": -1 + }, + "version": 2 +} \ No newline at end of file diff --git a/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json b/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json new file mode 100644 index 000000000..0222d4bdb --- /dev/null +++ b/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json @@ -0,0 +1,9 @@ +{ + "arch": "arm64", + "cpu": "Apple M1", + "machine": "Toms-MacBook-Air-2.local", + "num_cpu": "8", + "os": "Darwin 22.3.0", + "ram": "8589934592", + "version": 1 +} \ No newline at end of file diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json new file mode 100644 index 000000000..0db7fdbe5 --- /dev/null +++ b/benchmarks/.asv/results/benchmarks.json @@ -0,0 +1,41 @@ +{ + "kernels.TimeSuite.time_covfunc_call": { + "code": "class TimeSuite:\n def time_covfunc_call(self, kernel_func, n_datapoints, n_dims):\n self.kernelfunc.gram(self.X)\n\n def setup(self, kernel_func, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.uniform(\n key=key, minval=-3.0, maxval=3.0, shape=(n_datapoints, n_dims)\n )\n self.kernelfunc = get_kernel(kernel_name=kernel_func, n_dims=n_dims)", + "min_run_count": 2, + "name": "kernels.TimeSuite.time_covfunc_call", + "number": 0, + "param_names": [ + "kernel", + "n_data", + "dimensionality" + ], + "params": [ + [ + "'RBF'", + "'MATERN12'", + "'MATERN32'", + "'MATERN52'", + "'POLYNOMIAL'" + ], + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "60eb88777e78bdde3c136a83470d1f641bb9a146a66f763f64fd0acb21788765", + "warmup_time": -1 + }, + "version": 2 +} \ No newline at end of file diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json new file mode 100644 index 000000000..528d966cb --- /dev/null +++ b/benchmarks/asv.conf.json @@ -0,0 +1,102 @@ +{ + "version": 1, + + // The name of the project being benchmarked + "project": "gpjax", + + // The project's homepage + "project_url": "https://jaxgaussianprocesses.com/", + + // The URL or local path of the source code repository for the + // project being benchmarked + "repo": "..", + + // Customizable commands for building, installing, and + // uninstalling the project. See asv.conf.json documentation. + "install_command": ["python -mpip install {wheel_file}"], + // "install_command": ["in-dir={env_dir} python {conf_dir}/benchmarks_install.py {commit} {env_dir} {build_dir}"], + "build_command": [ + "PIP_NO_BUILD_ISOLATION=false python -m pip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" + ], + + // List of branches to benchmark. If not provided, defaults to "master" + // (for git) or "default" (for mercurial). + "branches": ["main"], // for git + // "branches": ["default"], // for mercurial + + // The DVCS being used. If not set, it will be automatically + // determined from "repo" by looking at the protocol in the URL + // (if remote), or by looking for special directories, such as + // ".git" (if local). + "dvcs": "git", + + // The tool to use to create environments. May be "conda", + // "virtualenv" or other value depending on the plugins in use. + // If missing or the empty string, the tool will be automatically + // determined by looking for tools on the PATH environment + // variable. + "environment_type": "virtualenv", + + // timeout in seconds for installing any dependencies in environment + // defaults to 10 min + //"install_timeout": 600, + + // the base URL to show a commit for the project. + "show_commit_url": "https://github.com/jaxgaussianprocesses/gpjax/commit/main", + + // The Pythons you'd like to test against. If not provided, defaults + // to the current version of Python used to run `asv`. + "pythons": ["3.8"], + + // The list of conda channel names to be searched for benchmark + // dependency packages in the specified order + // "conda_channels": ["conda-forge", "defaults"], + + // The directory (relative to the current directory) that benchmarks are + // stored in. If not provided, defaults to "benchmarks" + "benchmark_dir": ".", + + // The directory (relative to the current directory) to cache the Python + // environments in. If not provided, defaults to "env" + "env_dir": ".asv/env", + + // The directory (relative to the current directory) that raw benchmark + // results are stored in. If not provided, defaults to "results". + "results_dir": ".asv/results", + + // The directory (relative to the current directory) that the html tree + // should be written to. If not provided, defaults to "html". + "html_dir": "../docs/_build/html/benchmarks", + + // The number of characters to retain in the commit hashes. + // "hash_length": 8, + + // `asv` will cache results of the recent builds in each + // environment, making them faster to install next time. This is + // the number of builds to keep, per environment. + "build_cache_size": 2, + + // The commits after which the regression search in `asv publish` + // should start looking for regressions. Dictionary whose keys are + // regexps matching to benchmark names, and values corresponding to + // the commit (exclusive) after which to start looking for + // regressions. The default is to start from the first commit + // with results. If the commit is `null`, regression detection is + // skipped for the matching benchmark. + // + // "regressions_first_commits": { + // "some_benchmark": "352cdf", // Consider regressions only after this commit + // "another_benchmark": null, // Skip regression detection altogether + // }, + + // The thresholds for relative change in results, after which `asv + // publish` starts reporting regressions. Dictionary of the same + // form as in ``regressions_first_commits``, with values + // indicating the thresholds. If multiple entries match, the + // maximum is taken. If no entry matches, the default is 5%. + // + // "regressions_thresholds": { + // "some_benchmark": 0.01, // Threshold of 1% + // "another_benchmark": 0.5, // Threshold of 50% + // }, +} diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py new file mode 100644 index 000000000..4c06a1034 --- /dev/null +++ b/benchmarks/kernels.py @@ -0,0 +1,38 @@ +from gpjax import kernels +import jax.random as jr + +KERNEL_NAMES = ["RBF", "MATERN12", "MATERN32", "MATERN52", "POLYNOMIAL"] + +N_DATAPOINTS = [10, 100, 1000] +N_DIMS = [1, 2, 5] + + +def get_kernel(kernel_name: str, n_dims: int): + active_dims = list(range(n_dims)) + if kernel_name == "RBF": + return kernels.RBF(active_dims=active_dims) + elif kernel_name == "MATERN12": + return kernels.Matern12(active_dims=active_dims) + elif kernel_name == "MATERN32": + return kernels.Matern32(active_dims=active_dims) + elif kernel_name == "MATERN52": + return kernels.Matern52(active_dims=active_dims) + elif kernel_name == "POLYNOMIAL": + return kernels.Polynomial(active_dims=active_dims) + else: + raise ValueError("Unknown covariance function name") + + +class TimeSuite: + param_names = ["kernel", "n_data", "dimensionality"] + params = [KERNEL_NAMES, N_DATAPOINTS, N_DIMS] + + def setup(self, kernel_func, n_datapoints, n_dims): + key = jr.PRNGKey(123) + self.X = jr.uniform( + key=key, minval=-3.0, maxval=3.0, shape=(n_datapoints, n_dims) + ) + self.kernelfunc = get_kernel(kernel_name=kernel_func, n_dims=n_dims) + + def time_covfunc_call(self, kernel_func, n_datapoints, n_dims): + self.kernelfunc.gram(self.X) From d8503fc07de9454b6979410767c70f4849365767 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Thu, 15 Jun 2023 08:39:20 +0100 Subject: [PATCH 02/76] Add further benchamrks --- benchmarks/.asv/results/benchmarks.json | 58 ++++++++++++++++++------- benchmarks/kernels.py | 6 ++- benchmarks/linops.py | 33 ++++++++++++++ benchmarks/objectives.py | 34 +++++++++++++++ benchmarks/sparse.py | 38 ++++++++++++++++ 5 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 benchmarks/linops.py create mode 100644 benchmarks/objectives.py create mode 100644 benchmarks/sparse.py diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json index 0db7fdbe5..c6dfae04a 100644 --- a/benchmarks/.asv/results/benchmarks.json +++ b/benchmarks/.asv/results/benchmarks.json @@ -1,31 +1,59 @@ { - "kernels.TimeSuite.time_covfunc_call": { - "code": "class TimeSuite:\n def time_covfunc_call(self, kernel_func, n_datapoints, n_dims):\n self.kernelfunc.gram(self.X)\n\n def setup(self, kernel_func, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.uniform(\n key=key, minval=-3.0, maxval=3.0, shape=(n_datapoints, n_dims)\n )\n self.kernelfunc = get_kernel(kernel_name=kernel_func, n_dims=n_dims)", + "sparse.Sparse.time_eval": { + "code": "class Sparse:\n def time_eval(self, n_datapoints, n_dims):\n self.objective(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", "min_run_count": 2, - "name": "kernels.TimeSuite.time_covfunc_call", + "name": "sparse.Sparse.time_eval", "number": 0, "param_names": [ - "kernel", "n_data", - "dimensionality" + "n_inducing" ], "params": [ [ - "'RBF'", - "'MATERN12'", - "'MATERN32'", - "'MATERN52'", - "'POLYNOMIAL'" + "2000", + "5000", + "10000", + "20000" ], [ "10", + "20", + "50", "100", - "1000" + "200" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "c42a0cef98e7ce98940fdd14075c567a03ab6e0217008f317c0b2ad4bc48bccb", + "warmup_time": -1 + }, + "sparse.Sparse.time_grad": { + "code": "class Sparse:\n def time_grad(self, n_datapoints, n_dims):\n jax.grad(self.objective)(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", + "min_run_count": 2, + "name": "sparse.Sparse.time_grad", + "number": 0, + "param_names": [ + "n_data", + "n_inducing" + ], + "params": [ + [ + "2000", + "5000", + "10000", + "20000" ], [ - "1", - "2", - "5" + "10", + "20", + "50", + "100", + "200" ] ], "repeat": 0, @@ -34,7 +62,7 @@ "timeout": 60.0, "type": "time", "unit": "seconds", - "version": "60eb88777e78bdde3c136a83470d1f641bb9a146a66f763f64fd0acb21788765", + "version": "5aaf0153a37ed3daf24fa0e2a128884fc50602f21a8cc268d5ddb989aaabcd66", "warmup_time": -1 }, "version": 2 diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py index 4c06a1034..ecefc71fb 100644 --- a/benchmarks/kernels.py +++ b/benchmarks/kernels.py @@ -1,3 +1,7 @@ +from jax.config import config + +config.update("jax_enable_x64", True) + from gpjax import kernels import jax.random as jr @@ -23,7 +27,7 @@ def get_kernel(kernel_name: str, n_dims: int): raise ValueError("Unknown covariance function name") -class TimeSuite: +class Kernels: param_names = ["kernel", "n_data", "dimensionality"] params = [KERNEL_NAMES, N_DATAPOINTS, N_DIMS] diff --git a/benchmarks/linops.py b/benchmarks/linops.py new file mode 100644 index 000000000..30ff14e7d --- /dev/null +++ b/benchmarks/linops.py @@ -0,0 +1,33 @@ +from jax.config import config + +config.update("jax_enable_x64", True) + +from gpjax.linops import DenseLinearOperator +import jax.numpy as jnp +from sklearn.datasets import make_spd_matrix +import jax.random as jr + +N_DATAPOINTS = [10, 100, 200, 500, 1000] + + +class LinOps: + param_names = ["n_data"] + params = [N_DATAPOINTS] + + def setup(self, n_datapoints): + key = jr.PRNGKey(123) + self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123)) + self.y = jr.normal(key=key, shape=(n_datapoints, 1)) + self.linop = DenseLinearOperator(matrix=self.X) + + def time_root(self, n_datapoints): + self.linop.to_root() + + def time_inverse(self, n_datapoints): + self.linop.inverse() + + def time_logdet(self, n_datapoints): + self.linop.log_det() + + def time_solve(self, n_datapoints): + self.linop.solve(self.y) diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py new file mode 100644 index 000000000..f6ac1cb1b --- /dev/null +++ b/benchmarks/objectives.py @@ -0,0 +1,34 @@ +from jax.config import config + +config.update("jax_enable_x64", True) +import gpjax as gpx +import jax.numpy as jnp +import jax.random as jr +import jax + +N_DATAPOINTS = [10, 100, 200, 500, 1000] +N_DIMS = [1, 2, 5] +OBS = ["Gaussian", "Bernoulli"] + + +class Objectives: + param_names = ["n_data", "n_dims", "likelihood"] + params = [N_DATAPOINTS, N_DIMS, OBS] + + def setup(self, n_datapoints, n_dims, obs): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) + self.y = jnp.sin(self.X[:, :1]) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.posterior = self.prior * self.likelihood + self.objective = gpx.ConjugateMLL() + + def time_eval(self, n_datapoints, n_dims, obs): + self.objective(self.posterior, train_data=self.data) + + def time_grad(self, n_datapoints, n_dims, obs): + jax.grad(self.objective)(self.posterior, train_data=self.data) diff --git a/benchmarks/sparse.py b/benchmarks/sparse.py new file mode 100644 index 000000000..f83139012 --- /dev/null +++ b/benchmarks/sparse.py @@ -0,0 +1,38 @@ +from jax.config import config + +config.update("jax_enable_x64", True) +import gpjax as gpx +import jax.numpy as jnp +import jax.random as jr +import jax + +N_DATAPOINTS = [2000, 5000, 10000, 20000] +N_INDUCING = [10, 20, 50, 100, 200] + + +class Sparse: + param_names = ["n_data", "n_inducing"] + params = [N_DATAPOINTS, N_INDUCING] + + def setup(self, n_datapoints, n_inducing): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(n_datapoints, 1)) + self.y = jnp.sin(self.X[:, :1]) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(1))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.posterior = self.prior * self.likelihood + + Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1) + self.q = gpx.CollapsedVariationalGaussian( + posterior=self.posterior, inducing_inputs=Z + ) + self.objective = gpx.CollapsedELBO(negative=True) + + def time_eval(self, n_datapoints, n_dims): + self.objective(self.q, self.data) + + def time_grad(self, n_datapoints, n_dims): + jax.grad(self.objective)(self.q, self.data) From d2500375cc804001e36e2b8441c2435910f9808e Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Thu, 15 Jun 2023 22:43:14 +0100 Subject: [PATCH 03/76] Predictive benchmarks --- benchmarks/.asv/results/benchmarks.json | 64 ++++++++++++++----------- benchmarks/objectives.py | 26 ++++++---- benchmarks/predictions.py | 42 ++++++++++++++++ 3 files changed, 96 insertions(+), 36 deletions(-) create mode 100644 benchmarks/predictions.py diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json index c6dfae04a..9d1830c9e 100644 --- a/benchmarks/.asv/results/benchmarks.json +++ b/benchmarks/.asv/results/benchmarks.json @@ -1,26 +1,30 @@ { - "sparse.Sparse.time_eval": { - "code": "class Sparse:\n def time_eval(self, n_datapoints, n_dims):\n self.objective(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", + "objectives.Objectives.time_eval": { + "code": "class Objectives:\n def time_eval(self, n_datapoints, n_dims, likelihood):\n self.objective(self.posterior, train_data=self.data)\n\n def setup(self, n_datapoints, n_dims, likelihood):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n if likelihood == \"Bernoulli\":\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n if likelihood == \"Bernoulli\":\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n elif likelihood == \"Gaussian\":\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", "min_run_count": 2, - "name": "sparse.Sparse.time_eval", + "name": "objectives.Objectives.time_eval", "number": 0, "param_names": [ "n_data", - "n_inducing" + "n_dims", + "likelihood" ], "params": [ - [ - "2000", - "5000", - "10000", - "20000" - ], [ "10", - "20", - "50", "100", - "200" + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ], + [ + "'Gaussian'", + "'Bernoulli'" ] ], "repeat": 0, @@ -29,31 +33,35 @@ "timeout": 60.0, "type": "time", "unit": "seconds", - "version": "c42a0cef98e7ce98940fdd14075c567a03ab6e0217008f317c0b2ad4bc48bccb", + "version": "ba013def2ae4698fbe176bdeed5ed4e62f175feb5f89351a8e6223118526c63a", "warmup_time": -1 }, - "sparse.Sparse.time_grad": { - "code": "class Sparse:\n def time_grad(self, n_datapoints, n_dims):\n jax.grad(self.objective)(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", + "objectives.Objectives.time_grad": { + "code": "class Objectives:\n def time_grad(self, n_datapoints, n_dims, likelihood):\n jax.grad(self.objective)(self.posterior, train_data=self.data)\n\n def setup(self, n_datapoints, n_dims, likelihood):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n if likelihood == \"Bernoulli\":\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n if likelihood == \"Bernoulli\":\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n elif likelihood == \"Gaussian\":\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", "min_run_count": 2, - "name": "sparse.Sparse.time_grad", + "name": "objectives.Objectives.time_grad", "number": 0, "param_names": [ "n_data", - "n_inducing" + "n_dims", + "likelihood" ], "params": [ - [ - "2000", - "5000", - "10000", - "20000" - ], [ "10", - "20", - "50", "100", - "200" + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ], + [ + "'Gaussian'", + "'Bernoulli'" ] ], "repeat": 0, @@ -62,7 +70,7 @@ "timeout": 60.0, "type": "time", "unit": "seconds", - "version": "5aaf0153a37ed3daf24fa0e2a128884fc50602f21a8cc268d5ddb989aaabcd66", + "version": "19cae76dba5d83e53605707fcb7d0d9f8fee05aa83d2d744c1d6a52462576272", "warmup_time": -1 }, "version": 2 diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py index f6ac1cb1b..a0869f61d 100644 --- a/benchmarks/objectives.py +++ b/benchmarks/objectives.py @@ -8,27 +8,37 @@ N_DATAPOINTS = [10, 100, 200, 500, 1000] N_DIMS = [1, 2, 5] -OBS = ["Gaussian", "Bernoulli"] +LIKELIHOOD = ["Gaussian", "Bernoulli"] class Objectives: - param_names = ["n_data", "n_dims", "likelihood"] - params = [N_DATAPOINTS, N_DIMS, OBS] + param_names = [ + "n_data", + "n_dims", + "likelihood", + ] + params = [N_DATAPOINTS, N_DIMS, LIKELIHOOD] - def setup(self, n_datapoints, n_dims, obs): + def setup(self, n_datapoints, n_dims, likelihood): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) self.y = jnp.sin(self.X[:, :1]) + if likelihood == "Bernoulli": + self.y = jnp.where(self.y > 0, 1, 0) self.data = gpx.Dataset(X=self.X, y=self.y) kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) - self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + if likelihood == "Bernoulli": + self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) + self.objective = gpx.LogPosteriorDensity() + elif likelihood == "Gaussian": + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.objective = gpx.ConjugateMLL() self.posterior = self.prior * self.likelihood - self.objective = gpx.ConjugateMLL() - def time_eval(self, n_datapoints, n_dims, obs): + def time_eval(self, n_datapoints, n_dims, likelihood): self.objective(self.posterior, train_data=self.data) - def time_grad(self, n_datapoints, n_dims, obs): + def time_grad(self, n_datapoints, n_dims, likelihood): jax.grad(self.objective)(self.posterior, train_data=self.data) diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py new file mode 100644 index 000000000..fa45a51ff --- /dev/null +++ b/benchmarks/predictions.py @@ -0,0 +1,42 @@ +from jax.config import config + +config.update("jax_enable_x64", True) +import gpjax as gpx +from gpjax.gps import ConjugatePosterior +import jax.numpy as jnp +import jax.random as jr +import jax + +N_TEST = [100, 200, 500, 1000, 2000, 3000] +N_DIMS = [1, 2, 5] +LIKELIHOOD = ["Gaussian", "Bernoulli"] + + +class Objectives: + param_names = [ + "n_test", + "n_dims", + "likelihood", + ] + params = [N_TEST, N_DIMS, LIKELIHOOD] + + def setup(self, n_test, n_dims, likelihood): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(100, n_dims)) + self.y = jnp.sin(self.X[:, :1]) + if likelihood == "Bernoulli": + self.y = jnp.where(self.y > 0, 1, 0) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + if likelihood == "Bernoulli": + self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) + elif likelihood == "Gaussian": + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.posterior: ConjugatePosterior = self.prior * self.likelihood + key, subkey = jr.split(key) + self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) + + def time_predict(self, n_test, n_dims, likelihood): + self.posterior.predict(test_inputs=self.xtest, train_data=self.data) From b6fbd0af3f1e352de4a5e11224aeca97d16d5b4f Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Fri, 16 Jun 2023 08:17:48 +0100 Subject: [PATCH 04/76] Cleanup benchmarks --- benchmarks/.asv/results/benchmarks.json | 236 ++++++++++++++++++++++-- benchmarks/kernels.py | 110 ++++++++--- benchmarks/linops.py | 4 +- benchmarks/objectives.py | 82 ++++++-- benchmarks/predictions.py | 68 +++++-- benchmarks/sparse.py | 5 +- 6 files changed, 417 insertions(+), 88 deletions(-) diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json index 9d1830c9e..b57793eaa 100644 --- a/benchmarks/.asv/results/benchmarks.json +++ b/benchmarks/.asv/results/benchmarks.json @@ -1,30 +1,83 @@ { - "objectives.Objectives.time_eval": { - "code": "class Objectives:\n def time_eval(self, n_datapoints, n_dims, likelihood):\n self.objective(self.posterior, train_data=self.data)\n\n def setup(self, n_datapoints, n_dims, likelihood):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n if likelihood == \"Bernoulli\":\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n if likelihood == \"Bernoulli\":\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n elif likelihood == \"Gaussian\":\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", + "kernels.ArcCosine.time_covfunc_call": { + "code": "class ArcCosine:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims)))", "min_run_count": 2, - "name": "objectives.Objectives.time_eval", + "name": "kernels.ArcCosine.time_covfunc_call", "number": 0, "param_names": [ "n_data", - "n_dims", - "likelihood" + "dimensionality" ], "params": [ [ "10", "100", - "200", - "500", "1000" ], [ "1", "2", "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "f923a5feb1913469c66f702d89993918b418cc376b993df1cb7b974c3af01dfe", + "warmup_time": -1 + }, + "kernels.Linear.time_covfunc_call": { + "code": "class Linear:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Linear(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Linear.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "937688fe2a0aa44886c8c5856202502b9c82d2043d1034bf1c5984d73999b6b3", + "warmup_time": -1 + }, + "kernels.Matern12.time_covfunc_call": { + "code": "class Matern12:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern12(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Matern12.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" ], [ - "'Gaussian'", - "'Bernoulli'" + "1", + "2", + "5" ] ], "repeat": 0, @@ -33,35 +86,178 @@ "timeout": 60.0, "type": "time", "unit": "seconds", - "version": "ba013def2ae4698fbe176bdeed5ed4e62f175feb5f89351a8e6223118526c63a", + "version": "847a1c25403643211b2dbe93ac755ad2ddcd5da5e2b53136841d6ab99cc12699", "warmup_time": -1 }, - "objectives.Objectives.time_grad": { - "code": "class Objectives:\n def time_grad(self, n_datapoints, n_dims, likelihood):\n jax.grad(self.objective)(self.posterior, train_data=self.data)\n\n def setup(self, n_datapoints, n_dims, likelihood):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n if likelihood == \"Bernoulli\":\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n if likelihood == \"Bernoulli\":\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n elif likelihood == \"Gaussian\":\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", + "kernels.Matern32.time_covfunc_call": { + "code": "class Matern32:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern32(active_dims=list(range(n_dims)))", "min_run_count": 2, - "name": "objectives.Objectives.time_grad", + "name": "kernels.Matern32.time_covfunc_call", "number": 0, "param_names": [ "n_data", - "n_dims", - "likelihood" + "dimensionality" ], "params": [ [ "10", "100", - "200", - "500", "1000" ], [ "1", "2", "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "a520e46707f3b3181f63c1e1a372e9e6cea4d8bcfc1d24ab4b7f40ff1dadf171", + "warmup_time": -1 + }, + "kernels.Matern52.time_covfunc_call": { + "code": "class Matern52:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern52(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Matern52.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" ], [ - "'Gaussian'", - "'Bernoulli'" + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "179838852e999abcac68e90c141724342d0b4a25656f5ea7be6409ac9205b91f", + "warmup_time": -1 + }, + "kernels.Polynomial.time_covfunc_call": { + "code": "class Polynomial:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Polynomial(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Polynomial.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "67213fe983f9f09d6213609250aab0870f9b652c1fb08e07f68581af193365d5", + "warmup_time": -1 + }, + "kernels.PoweredExponential.time_covfunc_call": { + "code": "class PoweredExponential:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.PoweredExponential.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "2da6e3291d5e431eed969aaba40c4b42f226ebad022e3ea56b257ab2e2e97bb4", + "warmup_time": -1 + }, + "kernels.RBF.time_covfunc_call": { + "code": "class RBF:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RBF(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.RBF.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "timeout": 60.0, + "type": "time", + "unit": "seconds", + "version": "b52f5ad2fdad31ce7060e8eb015e77504de6b2566db3b05e702d48e17f7c3e7f", + "warmup_time": -1 + }, + "kernels.RationalQuadratic.time_covfunc_call": { + "code": "class RationalQuadratic:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.RationalQuadratic.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "1000" + ], + [ + "1", + "2", + "5" ] ], "repeat": 0, @@ -70,7 +266,7 @@ "timeout": 60.0, "type": "time", "unit": "seconds", - "version": "19cae76dba5d83e53605707fcb7d0d9f8fee05aa83d2d744c1d6a52462576272", + "version": "4ff62cadc9b2f84aa5f6ea06736910da029bd98f3f7191de57356b43d6915b42", "warmup_time": -1 }, "version": 2 diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py index ecefc71fb..0323b65b8 100644 --- a/benchmarks/kernels.py +++ b/benchmarks/kernels.py @@ -5,38 +5,94 @@ from gpjax import kernels import jax.random as jr -KERNEL_NAMES = ["RBF", "MATERN12", "MATERN32", "MATERN52", "POLYNOMIAL"] - -N_DATAPOINTS = [10, 100, 1000] -N_DIMS = [1, 2, 5] - - -def get_kernel(kernel_name: str, n_dims: int): - active_dims = list(range(n_dims)) - if kernel_name == "RBF": - return kernels.RBF(active_dims=active_dims) - elif kernel_name == "MATERN12": - return kernels.Matern12(active_dims=active_dims) - elif kernel_name == "MATERN32": - return kernels.Matern32(active_dims=active_dims) - elif kernel_name == "MATERN52": - return kernels.Matern52(active_dims=active_dims) - elif kernel_name == "POLYNOMIAL": - return kernels.Polynomial(active_dims=active_dims) - else: - raise ValueError("Unknown covariance function name") - class Kernels: - param_names = ["kernel", "n_data", "dimensionality"] - params = [KERNEL_NAMES, N_DATAPOINTS, N_DIMS] + param_names = ["n_data", "dimensionality"] + params = [[10, 100, 500, 1000, 2000], [1, 2, 5]] - def setup(self, kernel_func, n_datapoints, n_dims): + def setup(self, n_datapoints, n_dims): key = jr.PRNGKey(123) self.X = jr.uniform( key=key, minval=-3.0, maxval=3.0, shape=(n_datapoints, n_dims) ) - self.kernelfunc = get_kernel(kernel_name=kernel_func, n_dims=n_dims) - def time_covfunc_call(self, kernel_func, n_datapoints, n_dims): - self.kernelfunc.gram(self.X) + +class RBF(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.RBF(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class Matern12(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.Matern12(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class Matern32(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.Matern32(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class Matern52(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.Matern52(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class PoweredExponential(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class RationalQuadratic(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class Polynomial(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.Polynomial(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class Linear(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.Linear(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) + + +class ArcCosine(Kernels): + def setup(self, n_datapoints, n_dims): + super().setup(n_datapoints, n_dims) + self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims))) + + def time_covfunc_call(self, n_datapoints, n_dims): + self.kernel.gram(self.X) diff --git a/benchmarks/linops.py b/benchmarks/linops.py index 30ff14e7d..2b5def6a8 100644 --- a/benchmarks/linops.py +++ b/benchmarks/linops.py @@ -7,12 +7,10 @@ from sklearn.datasets import make_spd_matrix import jax.random as jr -N_DATAPOINTS = [10, 100, 200, 500, 1000] - class LinOps: param_names = ["n_data"] - params = [N_DATAPOINTS] + params = [[10, 100, 200, 500, 1000]] def setup(self, n_datapoints): key = jr.PRNGKey(123) diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py index a0869f61d..41adab175 100644 --- a/benchmarks/objectives.py +++ b/benchmarks/objectives.py @@ -6,39 +6,81 @@ import jax.random as jr import jax -N_DATAPOINTS = [10, 100, 200, 500, 1000] -N_DIMS = [1, 2, 5] -LIKELIHOOD = ["Gaussian", "Bernoulli"] - -class Objectives: +class Gaussian: param_names = [ "n_data", "n_dims", - "likelihood", ] - params = [N_DATAPOINTS, N_DIMS, LIKELIHOOD] + params = [[10, 100, 200, 500, 1000], [1, 2, 5]] - def setup(self, n_datapoints, n_dims, likelihood): + def setup(self, n_datapoints, n_dims): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) self.y = jnp.sin(self.X[:, :1]) - if likelihood == "Bernoulli": - self.y = jnp.where(self.y > 0, 1, 0) self.data = gpx.Dataset(X=self.X, y=self.y) kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) - if likelihood == "Bernoulli": - self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) - self.objective = gpx.LogPosteriorDensity() - elif likelihood == "Gaussian": - self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) - self.objective = gpx.ConjugateMLL() + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.objective = gpx.ConjugateMLL() + self.posterior = self.prior * self.likelihood + + def time_eval(self, n_datapoints, n_dims): + self.objective.step(self.posterior, self.data).block_until_ready() + + def time_grad(self, n_datapoints, n_dims): + jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) + + +class Bernoulli: + param_names = [ + "n_data", + "n_dims", + ] + params = [[10, 100, 200, 500, 1000], [1, 2, 5]] + + def setup(self, n_datapoints, n_dims): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) + self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) + self.objective = gpx.LogPosteriorDensity() + self.posterior = self.prior * self.likelihood + + def time_eval(self, n_datapoints, n_dims): + self.objective.step(self.posterior, self.data).block_until_ready() + + def time_grad(self, n_datapoints, n_dims): + jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) + + +class Poisson: + param_names = [ + "n_data", + "n_dims", + ] + params = [[10, 100, 200, 500, 1000], [1, 2, 5]] + + def setup(self, n_datapoints, n_dims): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) + f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function + self.y = jr.poisson(key, jnp.exp(f(self.X))) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Poisson(num_datapoints=self.data.n) + self.objective = gpx.LogPosteriorDensity() self.posterior = self.prior * self.likelihood - def time_eval(self, n_datapoints, n_dims, likelihood): - self.objective(self.posterior, train_data=self.data) + def time_eval(self, n_datapoints, n_dims): + self.objective.step(self.posterior, self.data).block_until_ready() - def time_grad(self, n_datapoints, n_dims, likelihood): - jax.grad(self.objective)(self.posterior, train_data=self.data) + def time_grad(self, n_datapoints, n_dims): + jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index fa45a51ff..cfbc2ff55 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -7,36 +7,76 @@ import jax.random as jr import jax -N_TEST = [100, 200, 500, 1000, 2000, 3000] -N_DIMS = [1, 2, 5] -LIKELIHOOD = ["Gaussian", "Bernoulli"] + +class Gaussian: + param_names = [ + "n_test", + "n_dims", + ] + params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] + + def setup(self, n_test, n_dims): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(100, n_dims)) + self.y = jnp.sin(self.X[:, :1]) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.posterior: ConjugatePosterior = self.prior * self.likelihood + key, subkey = jr.split(key) + self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) + + def time_predict(self, n_test, n_dims): + self.posterior.predict(test_inputs=self.xtest, train_data=self.data) -class Objectives: +class Bernoulli: param_names = [ "n_test", "n_dims", - "likelihood", ] - params = [N_TEST, N_DIMS, LIKELIHOOD] + params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] - def setup(self, n_test, n_dims, likelihood): + def setup(self, n_test, n_dims): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) self.y = jnp.sin(self.X[:, :1]) - if likelihood == "Bernoulli": - self.y = jnp.where(self.y > 0, 1, 0) + self.y = jnp.where(self.y > 0, 1, 0) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) + self.posterior: ConjugatePosterior = self.prior * self.likelihood + key, subkey = jr.split(key) + self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) + + def time_predict(self, n_test, n_dims): + self.posterior.predict(test_inputs=self.xtest, train_data=self.data) + + +class Poisson: + param_names = [ + "n_test", + "n_dims", + ] + params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] + + def setup(self, n_test, n_dims): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(100, n_dims)) + f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function + self.y = jr.poisson(key, jnp.exp(f(self.X))) self.data = gpx.Dataset(X=self.X, y=self.y) kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) - if likelihood == "Bernoulli": - self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) - elif likelihood == "Gaussian": - self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) self.posterior: ConjugatePosterior = self.prior * self.likelihood key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) - def time_predict(self, n_test, n_dims, likelihood): + def time_predict(self, n_test, n_dims): self.posterior.predict(test_inputs=self.xtest, train_data=self.data) diff --git a/benchmarks/sparse.py b/benchmarks/sparse.py index f83139012..fbd8462f2 100644 --- a/benchmarks/sparse.py +++ b/benchmarks/sparse.py @@ -6,13 +6,10 @@ import jax.random as jr import jax -N_DATAPOINTS = [2000, 5000, 10000, 20000] -N_INDUCING = [10, 20, 50, 100, 200] - class Sparse: param_names = ["n_data", "n_inducing"] - params = [N_DATAPOINTS, N_INDUCING] + params = [[2000, 5000, 10000, 20000], [10, 20, 50, 100, 200]] def setup(self, n_datapoints, n_inducing): key = jr.PRNGKey(123) From 1ad34911b7f1f28caab319468f3dadafd598e6a3 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Fri, 16 Jun 2023 08:19:41 +0100 Subject: [PATCH 05/76] Cleanup benchmarks --- benchmarks/.asv/results/benchmarks.json | 273 ------------------------ 1 file changed, 273 deletions(-) delete mode 100644 benchmarks/.asv/results/benchmarks.json diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json deleted file mode 100644 index b57793eaa..000000000 --- a/benchmarks/.asv/results/benchmarks.json +++ /dev/null @@ -1,273 +0,0 @@ -{ - "kernels.ArcCosine.time_covfunc_call": { - "code": "class ArcCosine:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.ArcCosine.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "f923a5feb1913469c66f702d89993918b418cc376b993df1cb7b974c3af01dfe", - "warmup_time": -1 - }, - "kernels.Linear.time_covfunc_call": { - "code": "class Linear:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Linear(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Linear.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "937688fe2a0aa44886c8c5856202502b9c82d2043d1034bf1c5984d73999b6b3", - "warmup_time": -1 - }, - "kernels.Matern12.time_covfunc_call": { - "code": "class Matern12:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern12(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern12.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "847a1c25403643211b2dbe93ac755ad2ddcd5da5e2b53136841d6ab99cc12699", - "warmup_time": -1 - }, - "kernels.Matern32.time_covfunc_call": { - "code": "class Matern32:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern32(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern32.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "a520e46707f3b3181f63c1e1a372e9e6cea4d8bcfc1d24ab4b7f40ff1dadf171", - "warmup_time": -1 - }, - "kernels.Matern52.time_covfunc_call": { - "code": "class Matern52:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern52(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern52.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "179838852e999abcac68e90c141724342d0b4a25656f5ea7be6409ac9205b91f", - "warmup_time": -1 - }, - "kernels.Polynomial.time_covfunc_call": { - "code": "class Polynomial:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Polynomial(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Polynomial.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "67213fe983f9f09d6213609250aab0870f9b652c1fb08e07f68581af193365d5", - "warmup_time": -1 - }, - "kernels.PoweredExponential.time_covfunc_call": { - "code": "class PoweredExponential:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.PoweredExponential.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "2da6e3291d5e431eed969aaba40c4b42f226ebad022e3ea56b257ab2e2e97bb4", - "warmup_time": -1 - }, - "kernels.RBF.time_covfunc_call": { - "code": "class RBF:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RBF(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.RBF.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "b52f5ad2fdad31ce7060e8eb015e77504de6b2566db3b05e702d48e17f7c3e7f", - "warmup_time": -1 - }, - "kernels.RationalQuadratic.time_covfunc_call": { - "code": "class RationalQuadratic:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.RationalQuadratic.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "4ff62cadc9b2f84aa5f6ea06736910da029bd98f3f7191de57356b43d6915b42", - "warmup_time": -1 - }, - "version": 2 -} \ No newline at end of file From f5ceb37d994ee33fda2bf5d61fb73d173eb81eeb Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Wed, 2 Aug 2023 17:06:31 +0100 Subject: [PATCH 06/76] completed notebook demonstrating vector fields with data --- docs/examples/data/UV_test_vortex.csv | 289 +++++++++++++++++ docs/examples/data/UV_train_vortex.csv | 8 + docs/examples/data/XY_test_vortex.csv | 289 +++++++++++++++++ docs/examples/data/XY_train_vortex.csv | 8 + docs/examples/vectorfields.py | 423 +++++++++++++++++++++++++ 5 files changed, 1017 insertions(+) create mode 100644 docs/examples/data/UV_test_vortex.csv create mode 100644 docs/examples/data/UV_train_vortex.csv create mode 100644 docs/examples/data/XY_test_vortex.csv create mode 100644 docs/examples/data/XY_train_vortex.csv create mode 100644 docs/examples/vectorfields.py diff --git a/docs/examples/data/UV_test_vortex.csv b/docs/examples/data/UV_test_vortex.csv new file mode 100644 index 000000000..35abb06e5 --- /dev/null +++ b/docs/examples/data/UV_test_vortex.csv @@ -0,0 +1,289 @@ +1.004967093467712402e+00,-1.006227016448974609e+00 +9.986173510551452637e-01,-8.796322345733642578e-01 +1.006476879119873047e+00,-7.600320577621459961e-01 +1.015230298042297363e+00,-6.385467052459716797e-01 +9.976584911346435547e-01,-5.017080903053283691e-01 +9.976586103439331055e-01,-3.841849565505981445e-01 +1.015792131423950195e+00,-2.722352147102355957e-01 +1.007674336433410645e+00,-1.338611394166946411e-01 +9.953052401542663574e-01,-1.733516715466976166e-02 +1.005425572395324707e+00,1.101694405078887939e-01 +9.953657984733581543e-01,2.307860851287841797e-01 +9.953427314758300781e-01,3.386488258838653564e-01 +1.002419590950012207e+00,4.637859463691711426e-01 +9.808672070503234863e-01,5.993096828460693359e-01 +9.827508330345153809e-01,7.203894257545471191e-01 +9.943771362304687500e-01,8.365256786346435547e-01 +9.898716807365417480e-01,9.603569507598876953e-01 +8.806934952735900879e-01,-9.872233271598815918e-01 +8.684707880020141602e-01,-8.834667205810546875e-01 +8.634279966354370117e-01,-7.496310472488403320e-01 +8.922075033187866211e-01,-6.346749663352966309e-01 +8.752932548522949219e-01,-5.123808979988098145e-01 +8.782262802124023438e-01,-3.767673373222351074e-01 +8.633035421371459961e-01,-2.570519447326660156e-01 +8.721072077751159668e-01,-1.347220391035079956e-01 +8.786602616310119629e-01,-7.353375200182199478e-03 +8.660410642623901367e-01,1.022508516907691956e-01 +8.813080191612243652e-01,2.313093245029449463e-01 +8.715446591377258301e-01,3.438360989093780518e-01 +8.746340870857238770e-01,4.726294279098510742e-01 +8.715339303016662598e-01,5.905352830886840820e-01 +8.960738182067871094e-01,7.152556777000427246e-01 +8.774160742759704590e-01,8.426862359046936035e-01 +8.669739365577697754e-01,9.510014653205871582e-01 +7.633274793624877930e-01,-9.790761470794677734e-01 +7.428935766220092773e-01,-8.876112103462219238e-01 +7.571907043457031250e-01,-7.672439217567443848e-01 +7.355053424835205078e-01,-6.210719347000122070e-01 +7.418201565742492676e-01,-5.022874474525451660e-01 +7.570706605911254883e-01,-3.815138936042785645e-01 +7.624866962432861328e-01,-2.590226531028747559e-01 +7.568157315254211426e-01,-1.429796069860458374e-01 +7.539455294609069824e-01,-2.938070707023143768e-02 +7.520909905433654785e-01,1.027988642454147339e-01 +7.403168082237243652e-01,2.177181839942932129e-01 +7.479035854339599609e-01,3.566899597644805908e-01 +7.504956722259521484e-01,4.679171741008758545e-01 +7.656732797622680664e-01,5.835817456245422363e-01 +7.585382461547851562e-01,7.110718488693237305e-01 +7.374716401100158691e-01,8.408640027046203613e-01 +7.583428621292114258e-01,9.535464048385620117e-01 +6.288022398948669434e-01,-1.008222222328186035e+00 +6.258838176727294922e-01,-8.751141428947448730e-01 +6.387698054313659668e-01,-7.526523470878601074e-01 +6.429630517959594727e-01,-6.377224922180175781e-01 +6.419658660888671875e-01,-5.149144530296325684e-01 +6.242609024047851562e-01,-3.854345977306365967e-01 +6.295609474182128906e-01,-2.797869741916656494e-01 +6.359657049179077148e-01,-1.569317877292633057e-01 +6.424084901809692383e-01,-2.759260497987270355e-02 +6.278613209724426270e-01,9.990634769201278687e-02 +6.307964920997619629e-01,2.275988757610321045e-01 +6.215897202491760254e-01,3.616923391819000244e-01 +6.206910014152526855e-01,4.779643416404724121e-01 +6.407783031463623047e-01,5.902373790740966797e-01 +6.462154388427734375e-01,7.140955328941345215e-01 +6.319329738616943359e-01,8.267093896865844727e-01 +6.426883935928344727e-01,9.589985609054565430e-01 +5.138204693794250488e-01,-1.002886533737182617e+00 +5.037528872489929199e-01,-8.743238449096679688e-01 +5.138180255889892578e-01,-7.633743286132812500e-01 +5.255844593048095703e-01,-6.274595856666564941e-01 +5.098457932472229004e-01,-4.948766827583312988e-01 +5.258505344390869141e-01,-3.888427019119262695e-01 +4.840066432952880859e-01,-2.612890005111694336e-01 +5.184230804443359375e-01,-1.359557062387466431e-01 +5.110745429992675781e-01,-2.442036755383014679e-02 +5.072140097618103027e-01,1.042817384004592896e-01 +5.111216902732849121e-01,2.246157228946685791e-01 +4.903284013271331787e-01,3.479155302047729492e-01 +5.080073475837707520e-01,4.616576433181762695e-01 +5.137752294540405273e-01,5.920818448066711426e-01 +5.249830484390258789e-01,7.192656993865966797e-01 +5.050213932991027832e-01,8.512461185455322266e-01 +5.021191239356994629e-01,9.687764048576354980e-01 +3.827375173568725586e-01,-9.784681797027587891e-01 +3.969091176986694336e-01,-8.852245211601257324e-01 +3.910426199436187744e-01,-7.463788390159606934e-01 +3.824574947357177734e-01,-6.308196187019348145e-01 +3.928877711296081543e-01,-4.883060455322265625e-01 +3.887258768081665039e-01,-3.958380818367004395e-01 +3.974415659904479980e-01,-2.737033367156982422e-01 +3.807345628738403320e-01,-1.488510668277740479e-01 +3.844784796237945557e-01,-4.164712131023406982e-02 +3.838340342044830322e-01,9.678326547145843506e-02 +3.731199502944946289e-01,2.168984711170196533e-01 +3.907163143157958984e-01,3.484427034854888916e-01 +3.903656601905822754e-01,4.728053212165832520e-01 +3.878062367439270020e-01,6.105984449386596680e-01 +3.854092359542846680e-01,7.237899303436279297e-01 +3.736014068126678467e-01,8.309656381607055664e-01 +3.835486471652984619e-01,9.501995444297790527e-01 +2.618789672851562500e-01,-9.950808286666870117e-01 +2.572833597660064697e-01,-8.907533288002014160e-01 +2.636932730674743652e-01,-7.367874383926391602e-01 +2.693466246128082275e-01,-6.208586692810058594e-01 +2.841679751873016357e-01,-5.148958563804626465e-01 +2.670519053936004639e-01,-4.048864543437957764e-01 +2.678816318511962891e-01,-2.517673969268798828e-01 +2.645616531372070312e-01,-1.440025418996810913e-01 +2.461184114217758179e-01,-8.030000142753124237e-03 +2.650409936904907227e-01,8.609654009342193604e-02 +2.659084200859069824e-01,2.184960395097732544e-01 +2.899385392665863037e-01,3.469912111759185791e-01 +2.633825242519378662e-01,4.698575735092163086e-01 +2.683216035366058350e-01,5.873360633850097656e-01 +2.649590075016021729e-01,7.205142378807067871e-01 +2.536193430423736572e-01,8.260585069656372070e-01 +2.767343521118164062e-01,9.577598571777343750e-01 +1.503764688968658447e-01,-9.987970590591430664e-01 +1.507674604654312134e-01,-8.724066615104675293e-01 +1.337632685899734497e-01,-7.479858994483947754e-01 +1.568850874900817871e-01,-6.438995003700256348e-01 +1.288386285305023193e-01,-5.255452394485473633e-01 +1.487257182598114014e-01,-3.749783337116241455e-01 +1.647616922855377197e-01,-2.619829773902893066e-01 +1.329517811536788940e-01,-1.503420025110244751e-01 +1.371941715478897095e-01,-4.896643571555614471e-03 +1.438536494970321655e-01,1.031975597143173218e-01 +1.378223896026611328e-01,2.362827658653259277e-01 +1.273505091667175293e-01,3.476139605045318604e-01 +1.435427665710449219e-01,4.899952411651611328e-01 +1.322341114282608032e-01,6.093901395797729492e-01 +1.475930660963058472e-01,7.117960453033447266e-01 +1.336628943681716919e-01,8.464503884315490723e-01 +1.583564877510070801e-01,9.656374454498291016e-01 +1.257563009858131409e-02,-9.863137006759643555e-01 +1.718754880130290985e-02,-8.872002363204956055e-01 +2.854333631694316864e-02,-7.482415437698364258e-01 +8.099519647657871246e-03,-6.220688223838806152e-01 +2.268276177346706390e-02,-5.277915000915527344e-01 +3.347958996891975403e-02,-3.995876908302307129e-01 +4.333330783993005753e-03,-2.856984436511993408e-01 +2.225450240075588226e-02,-1.455512046813964844e-01 +2.300699055194854736e-02,-1.323274057358503342e-02 +2.822639234364032745e-02,1.170643866062164307e-01 +8.038655854761600494e-03,2.252307385206222534e-01 +7.203597109764814377e-03,3.632249236106872559e-01 +2.562757954001426697e-02,4.555867314338684082e-01 +2.337801083922386169e-02,5.748029351234436035e-01 +2.291309088468551636e-02,7.137302160263061523e-01 +2.387264557182788849e-02,8.405753374099731445e-01 +1.360791642218828201e-02,9.588567018508911133e-01 +-9.971828013658523560e-02,-1.020674467086791992e+00 +-9.911008924245834351e-02,-8.784422278404235840e-01 +-1.091843321919441223e-01,-7.681467533111572266e-01 +-8.338306844234466553e-02,-6.259563565254211426e-01 +-9.730248898267745972e-02,-5.065380930900573730e-01 +-1.139538511633872986e-01,-3.971539139747619629e-01 +-9.547527879476547241e-02,-2.704447805881500244e-01 +-1.117876321077346802e-01,-1.534492820501327515e-01 +-9.416996687650680542e-02,-2.103495411574840546e-02 +-9.045486152172088623e-02,1.115922406315803528e-01 +-1.102476418018341064e-01,2.146325409412384033e-01 +-9.240705519914627075e-02,3.519792258739471436e-01 +-9.791300445795059204e-02,4.640851914882659912e-01 +-9.382021427154541016e-02,5.839080214500427246e-01 +-8.307288587093353271e-02,7.132154107093811035e-01 +-1.044946983456611633e-01,8.263822793960571289e-01 +-1.095781773328781128e-01,9.536471962928771973e-01 +-2.333849370479583740e-01,-1.011978745460510254e+00 +-2.326478958129882812e-01,-8.579037785530090332e-01 +-2.252608090639114380e-01,-7.547494173049926758e-01 +-2.210782766342163086e-01,-6.396503448486328125e-01 +-2.217228859663009644e-01,-5.080642700195312500e-01 +-2.162179648876190186e-01,-3.888783752918243408e-01 +-2.243597805500030518e-01,-2.675158083438873291e-01 +-2.099544554948806763e-01,-1.367154717445373535e-01 +-2.271363586187362671e-01,-1.283308584243059158e-02 +-1.972881108522415161e-01,9.673580527305603027e-02 +-2.182331234216690063e-01,2.187316119670867920e-01 +-2.330613732337951660e-01,3.441882729530334473e-01 +-2.351987212896347046e-01,4.463685452938079834e-01 +-2.196650654077529907e-01,5.766848325729370117e-01 +-2.267244309186935425e-01,7.279544472694396973e-01 +-2.173497974872589111e-01,8.531843423843383789e-01 +-2.197574228048324585e-01,9.566932916641235352e-01 +-3.476670682430267334e-01,-9.942344427108764648e-01 +-3.554067015647888184e-01,-8.744385242462158203e-01 +-3.620872497558593750e-01,-7.243132591247558594e-01 +-3.514039218425750732e-01,-6.214573383331298828e-01 +-3.383747935295104980e-01,-5.114832520484924316e-01 +-3.447978496551513672e-01,-3.973104953765869141e-01 +-3.593961596488952637e-01,-2.813705801963806152e-01 +-3.452069759368896484e-01,-1.408224999904632568e-01 +-3.430855870246887207e-01,-2.797167003154754639e-02 +-3.557773530483245850e-01,8.781827986240386963e-02 +-3.454015254974365234e-01,2.180240601301193237e-01 +-3.463566899299621582e-01,3.361232876777648926e-01 +-3.583684861660003662e-01,4.862591624259948730e-01 +-3.433609008789062500e-01,6.006531119346618652e-01 +-3.413309156894683838e-01,7.142059803009033203e-01 +-3.361082673072814941e-01,8.515341281890869141e-01 +-3.364007472991943359e-01,9.599573612213134766e-01 +-4.831644594669342041e-01,-1.008612871170043945e+00 +-4.787659943103790283e-01,-8.623197674751281738e-01 +-4.642373919486999512e-01,-7.497129440307617188e-01 +-4.642499089241027832e-01,-6.430255174636840820e-01 +-4.642372727394104004e-01,-5.121074914932250977e-01 +-4.308604300022125244e-01,-3.965112864971160889e-01 +-4.636788368225097656e-01,-2.791341245174407959e-01 +-4.580321013927459717e-01,-1.335953623056411743e-01 +-4.598477482795715332e-01,-1.313996850512921810e-03 +-4.628738462924957275e-01,8.805514127016067505e-02 +-4.725404381752014160e-01,2.301194816827774048e-01 +-4.617980718612670898e-01,3.404323458671569824e-01 +-4.771160185337066650e-01,4.645164906978607178e-01 +-4.717559516429901123e-01,5.859128236770629883e-01 +-4.742413759231567383e-01,7.056457996368408203e-01 +-4.685690104961395264e-01,8.372198939323425293e-01 +-4.462411701679229736e-01,9.508741497993469238e-01 +-6.105093955993652344e-01,-9.972954392433166504e-01 +-5.849741101264953613e-01,-8.780534267425537109e-01 +-6.079639196395874023e-01,-7.574915289878845215e-01 +-5.965560674667358398e-01,-6.417286992073059082e-01 +-5.809472203254699707e-01,-5.159717798233032227e-01 +-5.911939144134521484e-01,-3.802011907100677490e-01 +-6.026141643524169922e-01,-2.602969408035278320e-01 +-5.989897847175598145e-01,-1.526326984167098999e-01 +-5.850407481193542480e-01,-1.941484026610851288e-02 +-5.991404056549072266e-01,1.095546856522560120e-01 +-5.896721482276916504e-01,2.077957391738891602e-01 +-5.913810133934020996e-01,3.523723781108856201e-01 +-5.983527302742004395e-01,4.627615213394165039e-01 +-5.703973174095153809e-01,5.975427031517028809e-01 +-5.854975581169128418e-01,7.066531181335449219e-01 +-6.120881438255310059e-01,8.186858892440795898e-01 +-5.899721980094909668e-01,9.429082274436950684e-01 +-7.209035754203796387e-01,-9.995191693305969238e-01 +-7.057613730430603027e-01,-8.749538064002990723e-01 +-7.222109436988830566e-01,-7.641451954841613770e-01 +-7.154330611228942871e-01,-6.262671351432800293e-01 +-7.092358469963073730e-01,-5.268192887306213379e-01 +-7.056281566619873047e-01,-3.884159028530120850e-01 +-7.262886762619018555e-01,-2.774162888526916504e-01 +-7.176307439804077148e-01,-1.493754982948303223e-01 +-7.190351486206054688e-01,-1.993417739868164062e-02 +-7.208189964294433594e-01,9.343668073415756226e-02 +-6.966311931610107422e-01,2.206442356109619141e-01 +-7.102358937263488770e-01,3.570016920566558838e-01 +-7.268945574760437012e-01,4.636188447475433350e-01 +-7.051070928573608398e-01,6.001936793327331543e-01 +-6.930641531944274902e-01,7.029886245727539062e-01 +-7.039610743522644043e-01,8.420327305793762207e-01 +-7.294794321060180664e-01,9.735993742942810059e-01 +-8.415770530700683594e-01,-1.024716496467590332e+00 +-8.240655660629272461e-01,-8.855199813842773438e-01 +-8.438113927841186523e-01,-7.493312954902648926e-01 +-8.322964906692504883e-01,-6.346834897994995117e-01 +-8.289883732795715332e-01,-5.064926147460937500e-01 +-8.460040092468261719e-01,-3.937949538230895996e-01 +-8.373299241065979004e-01,-2.644402384757995605e-01 +-8.691473603248596191e-01,-1.444139182567596436e-01 +-8.469785451889038086e-01,-8.730342611670494080e-03 +-8.392603993415832520e-01,1.045850217342376709e-01 +-8.492125272750854492e-01,2.278658151626586914e-01 +-8.204106092453002930e-01,3.428200185298919678e-01 +-8.510361313819885254e-01,4.645116925239562988e-01 +-8.411351442337036133e-01,5.875111818313598633e-01 +-8.354272842407226562e-01,7.182302474975585938e-01 +-8.223219513893127441e-01,8.325248360633850098e-01 +-8.510932922363281250e-01,9.620814323425292969e-01 +-9.475520253181457520e-01,-9.792460203170776367e-01 +-9.590813517570495605e-01,-8.688398003578186035e-01 +-9.689987301826477051e-01,-7.583622932434082031e-01 +-9.545626640319824219e-01,-6.206409335136413574e-01 +-9.571930766105651855e-01,-5.142848491668701172e-01 +-9.651858210563659668e-01,-4.081363379955291748e-01 +-9.584856629371643066e-01,-2.753869891166687012e-01 +-9.630368351936340332e-01,-1.615650653839111328e-01 +-9.580485224723815918e-01,-2.392329834401607513e-02 +-9.525623917579650879e-01,1.022249981760978699e-01 +-9.433234930038452148e-01,2.412541657686233521e-01 +-9.715618491172790527e-01,3.502080440521240234e-01 +-9.378533363342285156e-01,4.671967625617980957e-01 +-9.787045717239379883e-01,6.001307964324951172e-01 +-9.607015252113342285e-01,6.921743750572204590e-01 +-9.533004760742187500e-01,8.390908241271972656e-01 +-9.563737511634826660e-01,9.668923020362854004e-01 diff --git a/docs/examples/data/UV_train_vortex.csv b/docs/examples/data/UV_train_vortex.csv new file mode 100644 index 000000000..cbee3ff20 --- /dev/null +++ b/docs/examples/data/UV_train_vortex.csv @@ -0,0 +1,8 @@ +-2.307565808296203613e-01,-5.147150158882141113e-01 +7.614375352859497070e-01,-9.592417478561401367e-01 +-7.997303605079650879e-01,-7.207061052322387695e-01 +-2.541528940200805664e-01,-9.593041539192199707e-01 +-6.932516098022460938e-01,-9.331753253936767578e-01 +2.270692773163318634e-02,-8.047766089439392090e-01 +3.859917819499969482e-01,-7.105028629302978516e-01 +9.024822115898132324e-01,-7.966634035110473633e-01 diff --git a/docs/examples/data/XY_test_vortex.csv b/docs/examples/data/XY_test_vortex.csv new file mode 100644 index 000000000..6d0a4cd02 --- /dev/null +++ b/docs/examples/data/XY_test_vortex.csv @@ -0,0 +1,289 @@ +-1.000000000000000000e+00,-1.000000000000000000e+00 +-8.775510191917419434e-01,-1.000000000000000000e+00 +-7.551020383834838867e-01,-1.000000000000000000e+00 +-6.326530575752258301e-01,-1.000000000000000000e+00 +-5.102040767669677734e-01,-1.000000000000000000e+00 +-3.877550959587097168e-01,-1.000000000000000000e+00 +-2.653061151504516602e-01,-1.000000000000000000e+00 +-1.428571492433547974e-01,-1.000000000000000000e+00 +-2.040816284716129303e-02,-1.000000000000000000e+00 +1.020408198237419128e-01,-1.000000000000000000e+00 +2.244897931814193726e-01,-1.000000000000000000e+00 +3.469387888908386230e-01,-1.000000000000000000e+00 +4.693877696990966797e-01,-1.000000000000000000e+00 +5.918367505073547363e-01,-1.000000000000000000e+00 +7.142857313156127930e-01,-1.000000000000000000e+00 +8.367347121238708496e-01,-1.000000000000000000e+00 +9.591836929321289062e-01,-1.000000000000000000e+00 +-1.000000000000000000e+00,-8.775510191917419434e-01 +-8.775510191917419434e-01,-8.775510191917419434e-01 +-7.551020383834838867e-01,-8.775510191917419434e-01 +-6.326530575752258301e-01,-8.775510191917419434e-01 +-5.102040767669677734e-01,-8.775510191917419434e-01 +-3.877550959587097168e-01,-8.775510191917419434e-01 +-2.653061151504516602e-01,-8.775510191917419434e-01 +-1.428571492433547974e-01,-8.775510191917419434e-01 +-2.040816284716129303e-02,-8.775510191917419434e-01 +1.020408198237419128e-01,-8.775510191917419434e-01 +2.244897931814193726e-01,-8.775510191917419434e-01 +3.469387888908386230e-01,-8.775510191917419434e-01 +4.693877696990966797e-01,-8.775510191917419434e-01 +5.918367505073547363e-01,-8.775510191917419434e-01 +7.142857313156127930e-01,-8.775510191917419434e-01 +8.367347121238708496e-01,-8.775510191917419434e-01 +9.591836929321289062e-01,-8.775510191917419434e-01 +-1.000000000000000000e+00,-7.551020383834838867e-01 +-8.775510191917419434e-01,-7.551020383834838867e-01 +-7.551020383834838867e-01,-7.551020383834838867e-01 +-6.326530575752258301e-01,-7.551020383834838867e-01 +-5.102040767669677734e-01,-7.551020383834838867e-01 +-3.877550959587097168e-01,-7.551020383834838867e-01 +-2.653061151504516602e-01,-7.551020383834838867e-01 +-1.428571492433547974e-01,-7.551020383834838867e-01 +-2.040816284716129303e-02,-7.551020383834838867e-01 +1.020408198237419128e-01,-7.551020383834838867e-01 +2.244897931814193726e-01,-7.551020383834838867e-01 +3.469387888908386230e-01,-7.551020383834838867e-01 +4.693877696990966797e-01,-7.551020383834838867e-01 +5.918367505073547363e-01,-7.551020383834838867e-01 +7.142857313156127930e-01,-7.551020383834838867e-01 +8.367347121238708496e-01,-7.551020383834838867e-01 +9.591836929321289062e-01,-7.551020383834838867e-01 +-1.000000000000000000e+00,-6.326530575752258301e-01 +-8.775510191917419434e-01,-6.326530575752258301e-01 +-7.551020383834838867e-01,-6.326530575752258301e-01 +-6.326530575752258301e-01,-6.326530575752258301e-01 +-5.102040767669677734e-01,-6.326530575752258301e-01 +-3.877550959587097168e-01,-6.326530575752258301e-01 +-2.653061151504516602e-01,-6.326530575752258301e-01 +-1.428571492433547974e-01,-6.326530575752258301e-01 +-2.040816284716129303e-02,-6.326530575752258301e-01 +1.020408198237419128e-01,-6.326530575752258301e-01 +2.244897931814193726e-01,-6.326530575752258301e-01 +3.469387888908386230e-01,-6.326530575752258301e-01 +4.693877696990966797e-01,-6.326530575752258301e-01 +5.918367505073547363e-01,-6.326530575752258301e-01 +7.142857313156127930e-01,-6.326530575752258301e-01 +8.367347121238708496e-01,-6.326530575752258301e-01 +9.591836929321289062e-01,-6.326530575752258301e-01 +-1.000000000000000000e+00,-5.102040767669677734e-01 +-8.775510191917419434e-01,-5.102040767669677734e-01 +-7.551020383834838867e-01,-5.102040767669677734e-01 +-6.326530575752258301e-01,-5.102040767669677734e-01 +-5.102040767669677734e-01,-5.102040767669677734e-01 +-3.877550959587097168e-01,-5.102040767669677734e-01 +-2.653061151504516602e-01,-5.102040767669677734e-01 +-1.428571492433547974e-01,-5.102040767669677734e-01 +-2.040816284716129303e-02,-5.102040767669677734e-01 +1.020408198237419128e-01,-5.102040767669677734e-01 +2.244897931814193726e-01,-5.102040767669677734e-01 +3.469387888908386230e-01,-5.102040767669677734e-01 +4.693877696990966797e-01,-5.102040767669677734e-01 +5.918367505073547363e-01,-5.102040767669677734e-01 +7.142857313156127930e-01,-5.102040767669677734e-01 +8.367347121238708496e-01,-5.102040767669677734e-01 +9.591836929321289062e-01,-5.102040767669677734e-01 +-1.000000000000000000e+00,-3.877550959587097168e-01 +-8.775510191917419434e-01,-3.877550959587097168e-01 +-7.551020383834838867e-01,-3.877550959587097168e-01 +-6.326530575752258301e-01,-3.877550959587097168e-01 +-5.102040767669677734e-01,-3.877550959587097168e-01 +-3.877550959587097168e-01,-3.877550959587097168e-01 +-2.653061151504516602e-01,-3.877550959587097168e-01 +-1.428571492433547974e-01,-3.877550959587097168e-01 +-2.040816284716129303e-02,-3.877550959587097168e-01 +1.020408198237419128e-01,-3.877550959587097168e-01 +2.244897931814193726e-01,-3.877550959587097168e-01 +3.469387888908386230e-01,-3.877550959587097168e-01 +4.693877696990966797e-01,-3.877550959587097168e-01 +5.918367505073547363e-01,-3.877550959587097168e-01 +7.142857313156127930e-01,-3.877550959587097168e-01 +8.367347121238708496e-01,-3.877550959587097168e-01 +9.591836929321289062e-01,-3.877550959587097168e-01 +-1.000000000000000000e+00,-2.653061151504516602e-01 +-8.775510191917419434e-01,-2.653061151504516602e-01 +-7.551020383834838867e-01,-2.653061151504516602e-01 +-6.326530575752258301e-01,-2.653061151504516602e-01 +-5.102040767669677734e-01,-2.653061151504516602e-01 +-3.877550959587097168e-01,-2.653061151504516602e-01 +-2.653061151504516602e-01,-2.653061151504516602e-01 +-1.428571492433547974e-01,-2.653061151504516602e-01 +-2.040816284716129303e-02,-2.653061151504516602e-01 +1.020408198237419128e-01,-2.653061151504516602e-01 +2.244897931814193726e-01,-2.653061151504516602e-01 +3.469387888908386230e-01,-2.653061151504516602e-01 +4.693877696990966797e-01,-2.653061151504516602e-01 +5.918367505073547363e-01,-2.653061151504516602e-01 +7.142857313156127930e-01,-2.653061151504516602e-01 +8.367347121238708496e-01,-2.653061151504516602e-01 +9.591836929321289062e-01,-2.653061151504516602e-01 +-1.000000000000000000e+00,-1.428571492433547974e-01 +-8.775510191917419434e-01,-1.428571492433547974e-01 +-7.551020383834838867e-01,-1.428571492433547974e-01 +-6.326530575752258301e-01,-1.428571492433547974e-01 +-5.102040767669677734e-01,-1.428571492433547974e-01 +-3.877550959587097168e-01,-1.428571492433547974e-01 +-2.653061151504516602e-01,-1.428571492433547974e-01 +-1.428571492433547974e-01,-1.428571492433547974e-01 +-2.040816284716129303e-02,-1.428571492433547974e-01 +1.020408198237419128e-01,-1.428571492433547974e-01 +2.244897931814193726e-01,-1.428571492433547974e-01 +3.469387888908386230e-01,-1.428571492433547974e-01 +4.693877696990966797e-01,-1.428571492433547974e-01 +5.918367505073547363e-01,-1.428571492433547974e-01 +7.142857313156127930e-01,-1.428571492433547974e-01 +8.367347121238708496e-01,-1.428571492433547974e-01 +9.591836929321289062e-01,-1.428571492433547974e-01 +-1.000000000000000000e+00,-2.040816284716129303e-02 +-8.775510191917419434e-01,-2.040816284716129303e-02 +-7.551020383834838867e-01,-2.040816284716129303e-02 +-6.326530575752258301e-01,-2.040816284716129303e-02 +-5.102040767669677734e-01,-2.040816284716129303e-02 +-3.877550959587097168e-01,-2.040816284716129303e-02 +-2.653061151504516602e-01,-2.040816284716129303e-02 +-1.428571492433547974e-01,-2.040816284716129303e-02 +-2.040816284716129303e-02,-2.040816284716129303e-02 +1.020408198237419128e-01,-2.040816284716129303e-02 +2.244897931814193726e-01,-2.040816284716129303e-02 +3.469387888908386230e-01,-2.040816284716129303e-02 +4.693877696990966797e-01,-2.040816284716129303e-02 +5.918367505073547363e-01,-2.040816284716129303e-02 +7.142857313156127930e-01,-2.040816284716129303e-02 +8.367347121238708496e-01,-2.040816284716129303e-02 +9.591836929321289062e-01,-2.040816284716129303e-02 +-1.000000000000000000e+00,1.020408198237419128e-01 +-8.775510191917419434e-01,1.020408198237419128e-01 +-7.551020383834838867e-01,1.020408198237419128e-01 +-6.326530575752258301e-01,1.020408198237419128e-01 +-5.102040767669677734e-01,1.020408198237419128e-01 +-3.877550959587097168e-01,1.020408198237419128e-01 +-2.653061151504516602e-01,1.020408198237419128e-01 +-1.428571492433547974e-01,1.020408198237419128e-01 +-2.040816284716129303e-02,1.020408198237419128e-01 +1.020408198237419128e-01,1.020408198237419128e-01 +2.244897931814193726e-01,1.020408198237419128e-01 +3.469387888908386230e-01,1.020408198237419128e-01 +4.693877696990966797e-01,1.020408198237419128e-01 +5.918367505073547363e-01,1.020408198237419128e-01 +7.142857313156127930e-01,1.020408198237419128e-01 +8.367347121238708496e-01,1.020408198237419128e-01 +9.591836929321289062e-01,1.020408198237419128e-01 +-1.000000000000000000e+00,2.244897931814193726e-01 +-8.775510191917419434e-01,2.244897931814193726e-01 +-7.551020383834838867e-01,2.244897931814193726e-01 +-6.326530575752258301e-01,2.244897931814193726e-01 +-5.102040767669677734e-01,2.244897931814193726e-01 +-3.877550959587097168e-01,2.244897931814193726e-01 +-2.653061151504516602e-01,2.244897931814193726e-01 +-1.428571492433547974e-01,2.244897931814193726e-01 +-2.040816284716129303e-02,2.244897931814193726e-01 +1.020408198237419128e-01,2.244897931814193726e-01 +2.244897931814193726e-01,2.244897931814193726e-01 +3.469387888908386230e-01,2.244897931814193726e-01 +4.693877696990966797e-01,2.244897931814193726e-01 +5.918367505073547363e-01,2.244897931814193726e-01 +7.142857313156127930e-01,2.244897931814193726e-01 +8.367347121238708496e-01,2.244897931814193726e-01 +9.591836929321289062e-01,2.244897931814193726e-01 +-1.000000000000000000e+00,3.469387888908386230e-01 +-8.775510191917419434e-01,3.469387888908386230e-01 +-7.551020383834838867e-01,3.469387888908386230e-01 +-6.326530575752258301e-01,3.469387888908386230e-01 +-5.102040767669677734e-01,3.469387888908386230e-01 +-3.877550959587097168e-01,3.469387888908386230e-01 +-2.653061151504516602e-01,3.469387888908386230e-01 +-1.428571492433547974e-01,3.469387888908386230e-01 +-2.040816284716129303e-02,3.469387888908386230e-01 +1.020408198237419128e-01,3.469387888908386230e-01 +2.244897931814193726e-01,3.469387888908386230e-01 +3.469387888908386230e-01,3.469387888908386230e-01 +4.693877696990966797e-01,3.469387888908386230e-01 +5.918367505073547363e-01,3.469387888908386230e-01 +7.142857313156127930e-01,3.469387888908386230e-01 +8.367347121238708496e-01,3.469387888908386230e-01 +9.591836929321289062e-01,3.469387888908386230e-01 +-1.000000000000000000e+00,4.693877696990966797e-01 +-8.775510191917419434e-01,4.693877696990966797e-01 +-7.551020383834838867e-01,4.693877696990966797e-01 +-6.326530575752258301e-01,4.693877696990966797e-01 +-5.102040767669677734e-01,4.693877696990966797e-01 +-3.877550959587097168e-01,4.693877696990966797e-01 +-2.653061151504516602e-01,4.693877696990966797e-01 +-1.428571492433547974e-01,4.693877696990966797e-01 +-2.040816284716129303e-02,4.693877696990966797e-01 +1.020408198237419128e-01,4.693877696990966797e-01 +2.244897931814193726e-01,4.693877696990966797e-01 +3.469387888908386230e-01,4.693877696990966797e-01 +4.693877696990966797e-01,4.693877696990966797e-01 +5.918367505073547363e-01,4.693877696990966797e-01 +7.142857313156127930e-01,4.693877696990966797e-01 +8.367347121238708496e-01,4.693877696990966797e-01 +9.591836929321289062e-01,4.693877696990966797e-01 +-1.000000000000000000e+00,5.918367505073547363e-01 +-8.775510191917419434e-01,5.918367505073547363e-01 +-7.551020383834838867e-01,5.918367505073547363e-01 +-6.326530575752258301e-01,5.918367505073547363e-01 +-5.102040767669677734e-01,5.918367505073547363e-01 +-3.877550959587097168e-01,5.918367505073547363e-01 +-2.653061151504516602e-01,5.918367505073547363e-01 +-1.428571492433547974e-01,5.918367505073547363e-01 +-2.040816284716129303e-02,5.918367505073547363e-01 +1.020408198237419128e-01,5.918367505073547363e-01 +2.244897931814193726e-01,5.918367505073547363e-01 +3.469387888908386230e-01,5.918367505073547363e-01 +4.693877696990966797e-01,5.918367505073547363e-01 +5.918367505073547363e-01,5.918367505073547363e-01 +7.142857313156127930e-01,5.918367505073547363e-01 +8.367347121238708496e-01,5.918367505073547363e-01 +9.591836929321289062e-01,5.918367505073547363e-01 +-1.000000000000000000e+00,7.142857313156127930e-01 +-8.775510191917419434e-01,7.142857313156127930e-01 +-7.551020383834838867e-01,7.142857313156127930e-01 +-6.326530575752258301e-01,7.142857313156127930e-01 +-5.102040767669677734e-01,7.142857313156127930e-01 +-3.877550959587097168e-01,7.142857313156127930e-01 +-2.653061151504516602e-01,7.142857313156127930e-01 +-1.428571492433547974e-01,7.142857313156127930e-01 +-2.040816284716129303e-02,7.142857313156127930e-01 +1.020408198237419128e-01,7.142857313156127930e-01 +2.244897931814193726e-01,7.142857313156127930e-01 +3.469387888908386230e-01,7.142857313156127930e-01 +4.693877696990966797e-01,7.142857313156127930e-01 +5.918367505073547363e-01,7.142857313156127930e-01 +7.142857313156127930e-01,7.142857313156127930e-01 +8.367347121238708496e-01,7.142857313156127930e-01 +9.591836929321289062e-01,7.142857313156127930e-01 +-1.000000000000000000e+00,8.367347121238708496e-01 +-8.775510191917419434e-01,8.367347121238708496e-01 +-7.551020383834838867e-01,8.367347121238708496e-01 +-6.326530575752258301e-01,8.367347121238708496e-01 +-5.102040767669677734e-01,8.367347121238708496e-01 +-3.877550959587097168e-01,8.367347121238708496e-01 +-2.653061151504516602e-01,8.367347121238708496e-01 +-1.428571492433547974e-01,8.367347121238708496e-01 +-2.040816284716129303e-02,8.367347121238708496e-01 +1.020408198237419128e-01,8.367347121238708496e-01 +2.244897931814193726e-01,8.367347121238708496e-01 +3.469387888908386230e-01,8.367347121238708496e-01 +4.693877696990966797e-01,8.367347121238708496e-01 +5.918367505073547363e-01,8.367347121238708496e-01 +7.142857313156127930e-01,8.367347121238708496e-01 +8.367347121238708496e-01,8.367347121238708496e-01 +9.591836929321289062e-01,8.367347121238708496e-01 +-1.000000000000000000e+00,9.591836929321289062e-01 +-8.775510191917419434e-01,9.591836929321289062e-01 +-7.551020383834838867e-01,9.591836929321289062e-01 +-6.326530575752258301e-01,9.591836929321289062e-01 +-5.102040767669677734e-01,9.591836929321289062e-01 +-3.877550959587097168e-01,9.591836929321289062e-01 +-2.653061151504516602e-01,9.591836929321289062e-01 +-1.428571492433547974e-01,9.591836929321289062e-01 +-2.040816284716129303e-02,9.591836929321289062e-01 +1.020408198237419128e-01,9.591836929321289062e-01 +2.244897931814193726e-01,9.591836929321289062e-01 +3.469387888908386230e-01,9.591836929321289062e-01 +4.693877696990966797e-01,9.591836929321289062e-01 +5.918367505073547363e-01,9.591836929321289062e-01 +7.142857313156127930e-01,9.591836929321289062e-01 +8.367347121238708496e-01,9.591836929321289062e-01 +9.591836929321289062e-01,9.591836929321289062e-01 diff --git a/docs/examples/data/XY_train_vortex.csv b/docs/examples/data/XY_train_vortex.csv new file mode 100644 index 000000000..10916c6e1 --- /dev/null +++ b/docs/examples/data/XY_train_vortex.csv @@ -0,0 +1,8 @@ +-8.999999761581420898e-01,8.999999761581420898e-01 +-9.499999880790710449e-01,-7.500000000000000000e-01 +-6.999999880790710449e-01,8.000000119209289551e-01 +-9.499999880790710449e-01,2.500000000000000000e-01 +-9.499999880790710449e-01,6.999999880790710449e-01 +-8.000000119209289551e-01,0.000000000000000000e+00 +-7.020655274391174316e-01,-3.841731250286102295e-01 +-8.000000119209289551e-01,-8.999999761581420898e-01 diff --git a/docs/examples/vectorfields.py b/docs/examples/vectorfields.py new file mode 100644 index 000000000..e5b2fc1e7 --- /dev/null +++ b/docs/examples/vectorfields.py @@ -0,0 +1,423 @@ +# %% [markdown] +# # Gaussian Processes for Vector Fields +# In this notebook, we use Gaussian processes to learn vector valued functions. We will be +# recreating the results by [Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf). +# %% +from jax.config import config +config.update("jax_enable_x64", True) +import torch +torch.manual_seed(123) +import jax.random as jr +import jax.numpy as jnp +from jaxtyping import install_import_hook +import matplotlib.pyplot as plt +from matplotlib import rcParams +from mpl_toolkits.axes_grid1 import make_axes_locatable +import numpy as onp +import optax as ox +import tensorflow_probability as tfp +from jax.config import config +from dataclasses import dataclass +from jaxtyping import ( + Array, + Float, + install_import_hook, +) +from jax import hessian, jit +with install_import_hook("gpjax", "beartype.beartype"): + import gpjax as gpx + +# Enable Float64 for more stable matrix inversions. +key = jr.PRNGKey(123) +plt.style.use( + "https://raw.githubusercontent.com/JaxGaussianProcesses/GPJax/main/docs/examples/gpjax.mplstyle" +) +cols = rcParams["axes.prop_cycle"].by_key()["color"] + +# jnp.set_printoptions(4, edgeitems=30, linewidth=100000, +# formatter=dict(float=lambda x: "%.3g" % x)) + + +# %% [markdown] +# ## Data Loading +# Data and original code are publicly available at https://github.com/renatoberlinghieri/Helmholtz-GP +# +# The data are 297 (artificial) measurements of ocean velocity, given by the vector field +# +# $$ +# \mathbf{F}(\mathbf{x}) = -x^{(1)}\hat{\imath} + x^{(0)}\hat{\jmath}, +# $$ +# +# +# +# where $\mathbf{x} = (x^{(0)}$,$x^{(1)})^\text{T}$, $\hat{\imath}$ and $\hat{\jmath}$ are unit vectors in the standard Cartesian directions (dimensions will be indicated by superscripts). +# +# The measurements are contained in a dataset $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_i$ is a 2 dimensional velocity vector and $\mathbf{x}_i$ is a 2 dimensional position vector on an $N=17\times17$ grid, equally spaced over the interval $[-1,1] \times[-1,1]$. 8 measurements of $\mathbf{F}(\mathbf{x})$ at new locations are contained in a dataset $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^8$, which are allocated to training data. +# +# + +# %% +#loading in data +try: + Pos_Train =onp.genfromtxt('data/XY_train_vortex.csv', delimiter=',').T + Pos_Test =onp.genfromtxt('data/XY_test_vortex.csv', delimiter=',').T + Vel_Train =onp.genfromtxt('data/UV_train_vortex.csv', delimiter=',').T + Vel_Test =onp.genfromtxt('data/UV_test_vortex.csv', delimiter=',').T +except FileNotFoundError: + Pos_Train =onp.genfromtxt('docs/examples/data/XY_train_vortex.csv', delimiter=',').T + Pos_Test =onp.genfromtxt('docs/examples/data/XY_test_vortex.csv', delimiter=',').T + Vel_Train =onp.genfromtxt('docs/examples/data/UV_train_vortex.csv', delimiter=',').T + Vel_Test =onp.genfromtxt('docs/examples/data/UV_test_vortex.csv', delimiter=',').T + + + +fig, ax = plt.subplots(1,1) +ax.quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = '$D_0$') +ax.quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', alpha = 0.7, label = '$D_T$') +ax.set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal') +ax.legend() +plt.show() + +# %% [markdown] +# ## Problem Setting +# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth ($D_0$). Note that the model only sees $D_T$, and $D_0$ is used in the final benchmark only. +# +# Since $\mathbf{F}$ is a vector-valued function, we would ideally require GPs that can learn vector-valued functions. Currently, GPJax only supports learning scalar-valued functions' GPs[1](#fn1) . However, since $D_T$ contains a 2D vector measurement $\mathbf{y}_{T,i}$ at each location $\mathbf{x}_{T,i}$, we may get around this by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. +# +# For a particular $\mathbf{y}$ (training or testing) at location $\mathbf{x}$, the components $(y^{(0)}, y^{(1)})$ are described by the latent vector field $\mathbf{F}$ such that +# +# $$ +# \mathbf{y} = \mathbf{F}(\mathbf{x}) = \left(\begin{array}{l} +# f^{(0)}\left(\mathbf{x}\right) \\ +# f^{(1)}\left(\mathbf{x}\right) +# \end{array}\right) +# $$ +# +# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that +# +# $$ +# g \left(\mathbf{x} , 0 \right) = f^{(0)} ( \mathbf{x} ), \text{and } g \left( \mathbf{x}, 1 \right)=f^{(1)}\left(\mathbf{x}\right). +# $$ +# +# We have increased the input dimension by 1, from the 2D $\mathbf{x}$ to 3D $\left(\mathbf{x}, 0\right)$ or $\left(\mathbf{x}, 1\right)$ +# +# By choosing the value of the third dimension, 0 or 1, we may now incorporate this information into computation of the kernel. +# We therefore make new 3D datasets $D_{T,3D} = \left\{\left( \mathbf{X}_{T,i},\mathbf{Y}_{T,i} \right) \right\} _{i=0}^{16}$ and $D_{0,3D} = \left\{\left( \mathbf{X}_{0,i},\mathbf{Y}_{0,i} \right) \right\} _{i=0}^{2N}$ that incorporates this new labelling, such that for each dataset (indicated by the subscript $D = 0$ or $D=T$), +# +# $$ +# X_{D,i} = \left( \mathbf{x}_{D,i}, z \right), +# $$ +# and +# $$ +# Y_{D,i} = y_{D,i}^{(z)}, +# $$ +# +# where $z = 0$ if $i$ is odd and $z=1$ if $i$ is even. + +# %% + +#introduce alternating z label +NTrain = len(Pos_Train[0]) +NTest = len(Pos_Test[0]) +zLabelTrain = jnp.tile(jnp.array([0.0,1.0]), NTrain) +zLabelTest = jnp.tile(jnp.array([0.0,1.0]), NTest) +#Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) using via the artificial z label +PosTrain3D = jnp.vstack((jnp.repeat(Pos_Train, repeats=2 , axis = 1), zLabelTrain)).T +VelTrain3D = Vel_Train.T.flatten().reshape(-1,1) +# we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points +PosTest3D = jnp.vstack((jnp.repeat(Pos_Test.reshape(2,289), repeats=2 , axis = 1), zLabelTest)).T +#Pass the labelled training data into gpx.dataset object +D0 = gpx.Dataset(X=PosTrain3D, y = VelTrain3D) + +# %% [markdown] +# ## Velocity (Dimension) Decomposition +# Having labelled the data, we are now in a position to use a GP to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly onto the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, +# +# $$ +# k_{\text{vel}} \left(\mathbf{X}, \mathbf{X}^{\prime}\right)= \begin{cases}k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right) & \text { if } z=z^{\prime} \\ 0 & \text { if } z \neq z^{\prime}\end{cases} +# $$ +# +# where $k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)$ are the user are kernels for each dimension. What this means is that there are no correlations between the $x^{(0)}$ and $x^{(1)}$ dimensions for all choices $\mathbf{X}$ and $\mathbf{X}^{\prime}$, since there are no off-diagonal elements in the Gram matrix populated by this choice. +# +# To implement this approach in GPJax, we define `VelocityKernel` in the following cell, following the steps outlined in the creating new kernels notebook. This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. +# + +# %% +from jax.numpy import exp +@dataclass +class VelocityKernel(gpx.kernels.AbstractKernel): + kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims = [0,1]) + kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims = [0,1]) + + def __call__( + self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] + ) -> Float[Array, "1"]: + #standard RBF-SE kernel is x and x' are on the same output, otherwise returns 0. acheive the correct value via 'Switches' + + z = X[2] + zp = Xp[2] + + k0Switch = (z+1)%2*(zp+1)%2 + k1Switch = z*zp + + return k0Switch*self.kernel0(X,Xp) + k1Switch*self.kernel1(X,Xp) + +# %% [markdown] +# ### GPJax Implementation +# Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean. We choose a Gaussian likelihood. +# + +# %% +#Define the Helmholtz GP +kernel = VelocityKernel() +mean = gpx.mean_functions.Zero() +Prior = gpx.Prior(mean_function=mean, kernel=kernel) +Likelihood = gpx.Gaussian(num_datapoints=D0.n, obs_noise=jnp.array([1.0],dtype=jnp.float64)) +Posterior = Prior*Likelihood + + +# %% [markdown] +# With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the marginal log likelihood using `optax`. We also plot its value at each step to visually confirm that we have found the minimum + +# %% + +#define the Marginal Log likelihood using D0 +Objective = gpx.objectives.ConjugateMLL(negative=True) +Objective(Posterior, train_data=D0) +Optimiser = ox.adam(learning_rate=0.01) +Objective = jit(Objective) + +NIters = 10000 +#Optimise to minimise the MLL +OptPosteriorVel, history = gpx.fit( + model=Posterior, + objective=Objective, + train_data=D0, + optim=Optimiser, + num_iters=NIters, + safe = True, + key=key, +) + +fig, ax = plt.subplots(1,1) +ax.plot(history, color = 'red') +ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") +plt.show() + +# %% [markdown] +# ### Comparison +# We next obtain the latent distribution of the GP of $g$ at $\mathbf{x}_{0,i}$, then extract its mean and standard at the test locations, $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, as well as the standard deviation (we will use it at the very end). + +# %% +VelocityLatent = OptPosteriorVel.predict(PosTest3D, train_data=D0) +VelocityMean = VelocityLatent.mean() +VelocityStd = VelocityLatent.stddev() +#extract x0 and x1 values over g +Vel_Lat = [VelocityMean[::2].reshape(17,17), VelocityMean[1::2].reshape(17,17)] +Pos_Lat = Pos_Test + +# %% [markdown] +# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. + +# %% + +#Residuals between ground truth and estimate +ResidualsVel = jnp.sqrt((Vel_Test[0].reshape(17,17)-Vel_Lat[0])**2+(Vel_Test[1].reshape(17,17)-Vel_Lat[1])**2) +X = Pos_Test[0] +Y = Pos_Test[1] + +#make figure +fig, ax = plt.subplots(1,3) +fig.tight_layout() +#ground truth +ax[0].quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', label = 'Testing Data') +ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = 'Training data') +ax[0].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Ground Truth') + +#Latent estimate of vector field F +ax[1].quiver(Pos_Lat[0],Pos_Lat[1], Vel_Lat[0], Vel_Lat[1], color = 'darkblue', label = 'Latent estimate of $\mathbf{F}$') +ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red') +ax[1].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'GP Latent Estimate') + +im = ax[2].imshow(ResidualsVel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap = 'hot') +ax[2].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Residuals') +fig.colorbar(im, fraction=0.046, pad=0.04, orientation='vertical') +plt.show() + +# %% [markdown] +# From the residuals it is evident the GP does not perform well far from the training data. This is because our construction of the kernel placed an independent prior on each physical dimension. This is incorrect, as by definition $f^{(z)}$ is directly proportional to $x^{(z^\prime)}$ for both physical dimensions. Therefore, we need a different approach that can implicitly incorporate this at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. + +# %% [markdown] +# ## Helmholtz Decomposition +# In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)): +# $$ +# \mathbf{F}=\operatorname{grad} \Phi+\operatorname{rot} \Psi +# $$ +# where +# $$ +# \operatorname{grad} \Phi:=\left[\begin{array}{l} +# \partial \Phi / \partial x^{(0)} \\ +# \partial \Phi / \partial x^{(1)} +# \end{array}\right] \text { and } \operatorname{rot} \Psi:=\left[\begin{array}{c} +# \partial \Psi / \partial x^{(1)} \\ +# -\partial \Psi / \partial x^{(0)} +# \end{array}\right] +# $$ +# +# This is reminiscent of a 3 dimensional [Helmholtz decomposition](https://en.wikipedia.org/wiki/Helmholtz_decomposition). +# +# The 2 dimensional decomposition motivates a different approach: placing priors on $\Psi$ and $\Phi$, allowing us to make assumptions directly about fundamental properties of $\mathbf{F}$. If we choose independent GP priors such that $\Phi \sim \mathcal{G P}\left(0, k_{\Phi}\right)$ and $\Psi \sim \mathcal{G P}\left(0, k_{\Psi}\right)$, then $\mathbf{F} \sim \mathcal{G P} \left(0, k_\text{Helm}\right)$ (since acting linear operations on a GPs give GPs). +# +# For $\mathbf{X}, \mathbf{X}^{\prime} \in \mathbb{R}^2 \times \left\{0,1\right\}$ and $z, z^\prime \in \{0,1\}$, +# +# $$ +# \boxed{ k_{\mathrm{Helm}}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)_{z,z^\prime} = \frac{\partial^2 k_{\Phi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial\left(x^{\prime}\right)^{(z^\prime)}}+(-1)^{z+z^\prime} \frac{\partial^2 k_{\Psi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(1-z)} \partial\left(x^{\prime}\right)^{(1-z^\prime)}}}. +# $$ +# +# where $x^{(z)}$ and $(x^\prime)^{(z^\prime)}$ are the $z$ and $z^\prime$ components of $\mathbf{X}$ and ${\mathbf{X}}^{\prime}$ respectively. +# +# We compute the second derivatives using `jax.hessian`. In the following implementation, for a kernel $k(\mathbf{x}, \mathbf{x}^{\prime})$, this computes the Hessian matrix with respect to the components of $\mathbf{x}$ +# +# $$ +# \frac{\partial^2 k\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial x^{(z^\prime)}}. +# $$ +# +# Note that we have operated $\dfrac{\partial}{\partial x^{(z)}}$, *not* $\dfrac{\partial}{\partial \left(x^\prime \right)^{(z)}}$, as the boxed equation suggests. This is not an issue if we choose stationary kernels $k(\mathbf{x}, \mathbf{x}^{\prime}) = k(\mathbf{x} - \mathbf{x}^{\prime})$ , as the partial derivatives with respect to the components have the following exchange symmetry: +# +# $$ +# \frac{\partial}{\partial x^{(z)}} = - \frac{\partial}{\partial \left( x^\prime \right)^{(z)}} +# $$ +# +# for either $z$. We specify that this implementation only works with stationary kernels by setting the type of `kernelPhi` and `kernelPsi` to `gpx.kernels.stationary`. +# %% + +@dataclass +class HelmholtzKernel(gpx.kernels.AbstractKernel): + #initialise Phi and Psi kernels as any stationary kernel in gpJax + kernelPhi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims = [0,1]) + kernelPsi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims = [0,1]) + + def __call__( + self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] + ) -> Float[Array, "1"]: + #obtain indices for k_helm, implement in the correct sign between the derivatives + z = jnp.array(X[2], dtype = int) + zp = jnp.array(Xp[2], dtype = int) + Sign = (-1)**(z+zp) + #convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) + DivPhi = -jnp.array(hessian(self.kernelPhi)(X,Xp),dtype = jnp.float64)[z][zp] + DivPsi = -jnp.array(hessian(self.kernelPsi)(X,Xp),dtype = jnp.float64)[1-z][1-zp] + + return DivPhi + Sign * DivPsi + +# %% [markdown] +# ### GPJax Implementation +# We repeat the exact same steps as with the velocity GP model, but replacing `VelocityKernel` with `HelmholtzKernel`. + +# %% +#Redefine Gaussian process with Helmholtz kernel +kernel = HelmholtzKernel() +Prior = gpx.Prior(mean_function=mean, kernel=kernel) +Likelihood = gpx.Gaussian(num_datapoints=D0.n, obs_noise=jnp.array([1.0],dtype=jnp.float64)) +Posterior = Prior*Likelihood + +#Optimise hyperparameters using optax +Objective = gpx.objectives.ConjugateMLL(negative=True) +Objective(Posterior, train_data=D0) +Optimiser = ox.adam(learning_rate=0.01) +Objective = jit(Objective) + +OptPosteriorHelm, history = gpx.fit( + model=Posterior, + objective=Objective, + train_data=D0, + optim=Optimiser, + num_iters=NIters, + safe = True, + key=key, +) + +fig, ax = plt.subplots(1,1) +ax.plot(history, color = 'red') +ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") +plt.show() + +#extract the mean +HelmholtzLatent = OptPosteriorHelm.predict(PosTest3D, train_data=D0) +HelmholtzMean = HelmholtzLatent.mean() +HelmholtzStd = HelmholtzLatent.stddev() +#extract x and y values over g +Helm_Lat = [HelmholtzMean[::2].reshape(17,17), HelmholtzMean[1::2].reshape(17,17)] +Pos_Lat = Pos_Test + +# %% [markdown] +# ### Comparison +# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. + +# %% + +#Residuals between ground truth and estimate +ResidualsHelm = jnp.sqrt((Vel_Test[0].reshape(17,17)-Helm_Lat[0])**2+(Vel_Test[1].reshape(17,17)-Helm_Lat[1])**2) +X = Pos_Test[0] +Y = Pos_Test[1] + +#make figure +fig, ax = plt.subplots(1,3) +fig.tight_layout() +#ground truth +ax[0].quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', label = 'Testing Data') +ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = 'Training data') +ax[0].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Ground Truth') +#Latent estimate of vector field F +ax[1].quiver(Pos_Lat[0],Pos_Lat[1], Helm_Lat[0], Helm_Lat[1], color = 'darkblue', label = 'Latent estimate of $\mathbf{F}$') +ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red') +ax[1].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'GP Latent Estimate of $\mathbf{F}$') +#Residuals +im = ax[2].imshow(ResidualsHelm, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap = 'hot') +ax[2].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Residuals') +fig.colorbar(im, fraction=0.046, pad=0.04, orientation='vertical') +plt.show() + +# %% [markdown] +# Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$, supportd by the residuals being much smaller than with the velocity decomposition. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). + + +# %% [markdown] +# ## Negative Log Predictive Densities +# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data, +# +# $$ +# \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right) +# $$ +# +# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. + +# %% +#ensure testing data alternates between x0 and x1 components +Vel_Query = jnp.column_stack((Vel_Test[0],Vel_Test[1])).flatten() + +NormalVel= tfp.substrates.jax.distributions.Normal( + loc = VelocityMean, + scale = VelocityStd, +) +NormalHelm= tfp.substrates.jax.distributions.Normal( + loc = HelmholtzMean, + scale = HelmholtzStd, +) + +NLPDVel = -jnp.sum(NormalVel.log_prob(Vel_Query)) +NLPDHelm = -jnp.sum(NormalHelm.log_prob(Vel_Query)) + +print("NLPD for Velocity: %.2f \nNLPD for Helmholtz: %.2f" % (NLPDVel, NLPDHelm)) +# %% [markdown] +# The Helmholtz model significantly outperforms the velocity model, as indicated by the lower NLPD score. + + +# %% [markdown] +# +# ## Footnote +# Kernels for vector valued functions have been studied in the literature, see [Alvarez et. al, (2012)](https://doi.org/10.48550/arXiv.1106.6251) +# ## System Configuration +# %% +# %reload_ext watermark +# %watermark -n -u -v -iv -w -a 'Ivan Shalashilin' From 527e9592dbbbd03df3d40901446929548071438b Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Wed, 2 Aug 2023 17:11:25 +0100 Subject: [PATCH 07/76] completed notebook demonstrating vector fields with data (correcly formatted) --- docs/examples/vectorfields.py | 318 +++++++++++++++++++++------------- 1 file changed, 194 insertions(+), 124 deletions(-) diff --git a/docs/examples/vectorfields.py b/docs/examples/vectorfields.py index e5b2fc1e7..89e40a674 100644 --- a/docs/examples/vectorfields.py +++ b/docs/examples/vectorfields.py @@ -1,11 +1,13 @@ # %% [markdown] # # Gaussian Processes for Vector Fields -# In this notebook, we use Gaussian processes to learn vector valued functions. We will be +# In this notebook, we use Gaussian processes to learn vector valued functions. We will be # recreating the results by [Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf). # %% from jax.config import config + config.update("jax_enable_x64", True) import torch + torch.manual_seed(123) import jax.random as jr import jax.numpy as jnp @@ -24,6 +26,7 @@ install_import_hook, ) from jax import hessian, jit + with install_import_hook("gpjax", "beartype.beartype"): import gpjax as gpx @@ -34,7 +37,7 @@ ) cols = rcParams["axes.prop_cycle"].by_key()["color"] -# jnp.set_printoptions(4, edgeitems=30, linewidth=100000, +# jnp.set_printoptions(4, edgeitems=30, linewidth=100000, # formatter=dict(float=lambda x: "%.3g" % x)) @@ -42,7 +45,7 @@ # ## Data Loading # Data and original code are publicly available at https://github.com/renatoberlinghieri/Helmholtz-GP # -# The data are 297 (artificial) measurements of ocean velocity, given by the vector field +# The data are 297 (artificial) measurements of ocean velocity, given by the vector field # # $$ # \mathbf{F}(\mathbf{x}) = -x^{(1)}\hat{\imath} + x^{(0)}\hat{\jmath}, @@ -57,32 +60,43 @@ # # %% -#loading in data +# loading in data try: - Pos_Train =onp.genfromtxt('data/XY_train_vortex.csv', delimiter=',').T - Pos_Test =onp.genfromtxt('data/XY_test_vortex.csv', delimiter=',').T - Vel_Train =onp.genfromtxt('data/UV_train_vortex.csv', delimiter=',').T - Vel_Test =onp.genfromtxt('data/UV_test_vortex.csv', delimiter=',').T + Pos_Train = onp.genfromtxt("data/XY_train_vortex.csv", delimiter=",").T + Pos_Test = onp.genfromtxt("data/XY_test_vortex.csv", delimiter=",").T + Vel_Train = onp.genfromtxt("data/UV_train_vortex.csv", delimiter=",").T + Vel_Test = onp.genfromtxt("data/UV_test_vortex.csv", delimiter=",").T except FileNotFoundError: - Pos_Train =onp.genfromtxt('docs/examples/data/XY_train_vortex.csv', delimiter=',').T - Pos_Test =onp.genfromtxt('docs/examples/data/XY_test_vortex.csv', delimiter=',').T - Vel_Train =onp.genfromtxt('docs/examples/data/UV_train_vortex.csv', delimiter=',').T - Vel_Test =onp.genfromtxt('docs/examples/data/UV_test_vortex.csv', delimiter=',').T - - - -fig, ax = plt.subplots(1,1) -ax.quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = '$D_0$') -ax.quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', alpha = 0.7, label = '$D_T$') -ax.set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal') + Pos_Train = onp.genfromtxt( + "docs/examples/data/XY_train_vortex.csv", delimiter="," + ).T + Pos_Test = onp.genfromtxt("docs/examples/data/XY_test_vortex.csv", delimiter=",").T + Vel_Train = onp.genfromtxt( + "docs/examples/data/UV_train_vortex.csv", delimiter="," + ).T + Vel_Test = onp.genfromtxt("docs/examples/data/UV_test_vortex.csv", delimiter=",").T + + +fig, ax = plt.subplots(1, 1) +ax.quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="$D_0$") +ax.quiver( + Pos_Train[0], + Pos_Train[1], + Vel_Train[0], + Vel_Train[1], + color="red", + alpha=0.7, + label="$D_T$", +) +ax.set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal") ax.legend() plt.show() # %% [markdown] # ## Problem Setting -# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth ($D_0$). Note that the model only sees $D_T$, and $D_0$ is used in the final benchmark only. +# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth ($D_0$). Note that the model only sees $D_T$, and $D_0$ is used in the final benchmark only. # -# Since $\mathbf{F}$ is a vector-valued function, we would ideally require GPs that can learn vector-valued functions. Currently, GPJax only supports learning scalar-valued functions' GPs[1](#fn1) . However, since $D_T$ contains a 2D vector measurement $\mathbf{y}_{T,i}$ at each location $\mathbf{x}_{T,i}$, we may get around this by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. +# Since $\mathbf{F}$ is a vector-valued function, we would ideally require GPs that can learn vector-valued functions. Currently, GPJax only supports learning scalar-valued functions' GPs[1](#fn1) . However, since $D_T$ contains a 2D vector measurement $\mathbf{y}_{T,i}$ at each location $\mathbf{x}_{T,i}$, we may get around this by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. # # For a particular $\mathbf{y}$ (training or testing) at location $\mathbf{x}$, the components $(y^{(0)}, y^{(1)})$ are described by the latent vector field $\mathbf{F}$ such that # @@ -93,7 +107,7 @@ # \end{array}\right) # $$ # -# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that +# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that # # $$ # g \left(\mathbf{x} , 0 \right) = f^{(0)} ( \mathbf{x} ), \text{and } g \left( \mathbf{x}, 1 \right)=f^{(1)}\left(\mathbf{x}\right). @@ -106,8 +120,8 @@ # # $$ # X_{D,i} = \left( \mathbf{x}_{D,i}, z \right), -# $$ -# and +# $$ +# and # $$ # Y_{D,i} = y_{D,i}^{(z)}, # $$ @@ -116,21 +130,23 @@ # %% -#introduce alternating z label +# introduce alternating z label NTrain = len(Pos_Train[0]) NTest = len(Pos_Test[0]) -zLabelTrain = jnp.tile(jnp.array([0.0,1.0]), NTrain) -zLabelTest = jnp.tile(jnp.array([0.0,1.0]), NTest) -#Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) using via the artificial z label -PosTrain3D = jnp.vstack((jnp.repeat(Pos_Train, repeats=2 , axis = 1), zLabelTrain)).T -VelTrain3D = Vel_Train.T.flatten().reshape(-1,1) +zLabelTrain = jnp.tile(jnp.array([0.0, 1.0]), NTrain) +zLabelTest = jnp.tile(jnp.array([0.0, 1.0]), NTest) +# Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) using via the artificial z label +PosTrain3D = jnp.vstack((jnp.repeat(Pos_Train, repeats=2, axis=1), zLabelTrain)).T +VelTrain3D = Vel_Train.T.flatten().reshape(-1, 1) # we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points -PosTest3D = jnp.vstack((jnp.repeat(Pos_Test.reshape(2,289), repeats=2 , axis = 1), zLabelTest)).T -#Pass the labelled training data into gpx.dataset object -D0 = gpx.Dataset(X=PosTrain3D, y = VelTrain3D) +PosTest3D = jnp.vstack( + (jnp.repeat(Pos_Test.reshape(2, 289), repeats=2, axis=1), zLabelTest) +).T +# Pass the labelled training data into gpx.dataset object +D0 = gpx.Dataset(X=PosTrain3D, y=VelTrain3D) # %% [markdown] -# ## Velocity (Dimension) Decomposition +# ## Velocity (Dimension) Decomposition # Having labelled the data, we are now in a position to use a GP to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly onto the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, # # $$ @@ -144,23 +160,26 @@ # %% from jax.numpy import exp + + @dataclass class VelocityKernel(gpx.kernels.AbstractKernel): - kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims = [0,1]) - kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims = [0,1]) + kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) + kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) def __call__( self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] ) -> Float[Array, "1"]: - #standard RBF-SE kernel is x and x' are on the same output, otherwise returns 0. acheive the correct value via 'Switches' - + # standard RBF-SE kernel is x and x' are on the same output, otherwise returns 0. acheive the correct value via 'Switches' + z = X[2] zp = Xp[2] - - k0Switch = (z+1)%2*(zp+1)%2 - k1Switch = z*zp - - return k0Switch*self.kernel0(X,Xp) + k1Switch*self.kernel1(X,Xp) + + k0Switch = (z + 1) % 2 * (zp + 1) % 2 + k1Switch = z * zp + + return k0Switch * self.kernel0(X, Xp) + k1Switch * self.kernel1(X, Xp) + # %% [markdown] # ### GPJax Implementation @@ -168,12 +187,14 @@ def __call__( # # %% -#Define the Helmholtz GP +# Define the Helmholtz GP kernel = VelocityKernel() mean = gpx.mean_functions.Zero() Prior = gpx.Prior(mean_function=mean, kernel=kernel) -Likelihood = gpx.Gaussian(num_datapoints=D0.n, obs_noise=jnp.array([1.0],dtype=jnp.float64)) -Posterior = Prior*Likelihood +Likelihood = gpx.Gaussian( + num_datapoints=D0.n, obs_noise=jnp.array([1.0], dtype=jnp.float64) +) +Posterior = Prior * Likelihood # %% [markdown] @@ -181,67 +202,86 @@ def __call__( # %% -#define the Marginal Log likelihood using D0 +# define the Marginal Log likelihood using D0 Objective = gpx.objectives.ConjugateMLL(negative=True) -Objective(Posterior, train_data=D0) +Objective(Posterior, train_data=D0) Optimiser = ox.adam(learning_rate=0.01) Objective = jit(Objective) NIters = 10000 -#Optimise to minimise the MLL +# Optimise to minimise the MLL OptPosteriorVel, history = gpx.fit( model=Posterior, objective=Objective, train_data=D0, optim=Optimiser, num_iters=NIters, - safe = True, + safe=True, key=key, ) -fig, ax = plt.subplots(1,1) -ax.plot(history, color = 'red') +fig, ax = plt.subplots(1, 1) +ax.plot(history, color="red") ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") plt.show() # %% [markdown] -# ### Comparison +# ### Comparison # We next obtain the latent distribution of the GP of $g$ at $\mathbf{x}_{0,i}$, then extract its mean and standard at the test locations, $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, as well as the standard deviation (we will use it at the very end). # %% VelocityLatent = OptPosteriorVel.predict(PosTest3D, train_data=D0) VelocityMean = VelocityLatent.mean() VelocityStd = VelocityLatent.stddev() -#extract x0 and x1 values over g -Vel_Lat = [VelocityMean[::2].reshape(17,17), VelocityMean[1::2].reshape(17,17)] +# extract x0 and x1 values over g +Vel_Lat = [VelocityMean[::2].reshape(17, 17), VelocityMean[1::2].reshape(17, 17)] Pos_Lat = Pos_Test # %% [markdown] -# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. +# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. # %% -#Residuals between ground truth and estimate -ResidualsVel = jnp.sqrt((Vel_Test[0].reshape(17,17)-Vel_Lat[0])**2+(Vel_Test[1].reshape(17,17)-Vel_Lat[1])**2) +# Residuals between ground truth and estimate +ResidualsVel = jnp.sqrt( + (Vel_Test[0].reshape(17, 17) - Vel_Lat[0]) ** 2 + + (Vel_Test[1].reshape(17, 17) - Vel_Lat[1]) ** 2 +) X = Pos_Test[0] Y = Pos_Test[1] -#make figure -fig, ax = plt.subplots(1,3) +# make figure +fig, ax = plt.subplots(1, 3) fig.tight_layout() -#ground truth -ax[0].quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', label = 'Testing Data') -ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = 'Training data') -ax[0].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Ground Truth') - -#Latent estimate of vector field F -ax[1].quiver(Pos_Lat[0],Pos_Lat[1], Vel_Lat[0], Vel_Lat[1], color = 'darkblue', label = 'Latent estimate of $\mathbf{F}$') -ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red') -ax[1].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'GP Latent Estimate') - -im = ax[2].imshow(ResidualsVel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap = 'hot') -ax[2].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Residuals') -fig.colorbar(im, fraction=0.046, pad=0.04, orientation='vertical') +# ground truth +ax[0].quiver( + Pos_Train[0], + Pos_Train[1], + Vel_Train[0], + Vel_Train[1], + color="red", + label="Testing Data", +) +ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="Training data") +ax[0].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Ground Truth") + +# Latent estimate of vector field F +ax[1].quiver( + Pos_Lat[0], + Pos_Lat[1], + Vel_Lat[0], + Vel_Lat[1], + color="darkblue", + label="Latent estimate of $\mathbf{F}$", +) +ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color="red") +ax[1].set( + xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="GP Latent Estimate" +) + +im = ax[2].imshow(ResidualsVel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="hot") +ax[2].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Residuals") +fig.colorbar(im, fraction=0.046, pad=0.04, orientation="vertical") plt.show() # %% [markdown] @@ -291,39 +331,45 @@ def __call__( # for either $z$. We specify that this implementation only works with stationary kernels by setting the type of `kernelPhi` and `kernelPsi` to `gpx.kernels.stationary`. # %% + @dataclass class HelmholtzKernel(gpx.kernels.AbstractKernel): - #initialise Phi and Psi kernels as any stationary kernel in gpJax - kernelPhi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims = [0,1]) - kernelPsi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims = [0,1]) - + # initialise Phi and Psi kernels as any stationary kernel in gpJax + kernelPhi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims=[0, 1]) + kernelPsi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims=[0, 1]) + def __call__( self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] ) -> Float[Array, "1"]: - #obtain indices for k_helm, implement in the correct sign between the derivatives - z = jnp.array(X[2], dtype = int) - zp = jnp.array(Xp[2], dtype = int) - Sign = (-1)**(z+zp) - #convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) - DivPhi = -jnp.array(hessian(self.kernelPhi)(X,Xp),dtype = jnp.float64)[z][zp] - DivPsi = -jnp.array(hessian(self.kernelPsi)(X,Xp),dtype = jnp.float64)[1-z][1-zp] + # obtain indices for k_helm, implement in the correct sign between the derivatives + z = jnp.array(X[2], dtype=int) + zp = jnp.array(Xp[2], dtype=int) + Sign = (-1) ** (z + zp) + # convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) + DivPhi = -jnp.array(hessian(self.kernelPhi)(X, Xp), dtype=jnp.float64)[z][zp] + DivPsi = -jnp.array(hessian(self.kernelPsi)(X, Xp), dtype=jnp.float64)[1 - z][ + 1 - zp + ] return DivPhi + Sign * DivPsi + # %% [markdown] # ### GPJax Implementation # We repeat the exact same steps as with the velocity GP model, but replacing `VelocityKernel` with `HelmholtzKernel`. # %% -#Redefine Gaussian process with Helmholtz kernel +# Redefine Gaussian process with Helmholtz kernel kernel = HelmholtzKernel() Prior = gpx.Prior(mean_function=mean, kernel=kernel) -Likelihood = gpx.Gaussian(num_datapoints=D0.n, obs_noise=jnp.array([1.0],dtype=jnp.float64)) -Posterior = Prior*Likelihood +Likelihood = gpx.Gaussian( + num_datapoints=D0.n, obs_noise=jnp.array([1.0], dtype=jnp.float64) +) +Posterior = Prior * Likelihood -#Optimise hyperparameters using optax +# Optimise hyperparameters using optax Objective = gpx.objectives.ConjugateMLL(negative=True) -Objective(Posterior, train_data=D0) +Objective(Posterior, train_data=D0) Optimiser = ox.adam(learning_rate=0.01) Objective = jit(Objective) @@ -333,49 +379,73 @@ def __call__( train_data=D0, optim=Optimiser, num_iters=NIters, - safe = True, + safe=True, key=key, ) -fig, ax = plt.subplots(1,1) -ax.plot(history, color = 'red') +fig, ax = plt.subplots(1, 1) +ax.plot(history, color="red") ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") plt.show() -#extract the mean +# extract the mean HelmholtzLatent = OptPosteriorHelm.predict(PosTest3D, train_data=D0) HelmholtzMean = HelmholtzLatent.mean() HelmholtzStd = HelmholtzLatent.stddev() -#extract x and y values over g -Helm_Lat = [HelmholtzMean[::2].reshape(17,17), HelmholtzMean[1::2].reshape(17,17)] +# extract x and y values over g +Helm_Lat = [HelmholtzMean[::2].reshape(17, 17), HelmholtzMean[1::2].reshape(17, 17)] Pos_Lat = Pos_Test # %% [markdown] -# ### Comparison -# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. +# ### Comparison +# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. # %% -#Residuals between ground truth and estimate -ResidualsHelm = jnp.sqrt((Vel_Test[0].reshape(17,17)-Helm_Lat[0])**2+(Vel_Test[1].reshape(17,17)-Helm_Lat[1])**2) +# Residuals between ground truth and estimate +ResidualsHelm = jnp.sqrt( + (Vel_Test[0].reshape(17, 17) - Helm_Lat[0]) ** 2 + + (Vel_Test[1].reshape(17, 17) - Helm_Lat[1]) ** 2 +) X = Pos_Test[0] Y = Pos_Test[1] -#make figure -fig, ax = plt.subplots(1,3) +# make figure +fig, ax = plt.subplots(1, 3) fig.tight_layout() -#ground truth -ax[0].quiver(Pos_Train[0],Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red', label = 'Testing Data') -ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label = 'Training data') -ax[0].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Ground Truth') -#Latent estimate of vector field F -ax[1].quiver(Pos_Lat[0],Pos_Lat[1], Helm_Lat[0], Helm_Lat[1], color = 'darkblue', label = 'Latent estimate of $\mathbf{F}$') -ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color = 'red') -ax[1].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'GP Latent Estimate of $\mathbf{F}$') -#Residuals -im = ax[2].imshow(ResidualsHelm, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap = 'hot') -ax[2].set(xlim = [-1.3,1.3], ylim = [-1.3,1.3], aspect = 'equal', title = 'Residuals') -fig.colorbar(im, fraction=0.046, pad=0.04, orientation='vertical') +# ground truth +ax[0].quiver( + Pos_Train[0], + Pos_Train[1], + Vel_Train[0], + Vel_Train[1], + color="red", + label="Testing Data", +) +ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="Training data") +ax[0].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Ground Truth") +# Latent estimate of vector field F +ax[1].quiver( + Pos_Lat[0], + Pos_Lat[1], + Helm_Lat[0], + Helm_Lat[1], + color="darkblue", + label="Latent estimate of $\mathbf{F}$", +) +ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color="red") +ax[1].set( + xlim=[-1.3, 1.3], + ylim=[-1.3, 1.3], + aspect="equal", + title="GP Latent Estimate of $\mathbf{F}$", +) +# Residuals +im = ax[2].imshow( + ResidualsHelm, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="hot" +) +ax[2].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Residuals") +fig.colorbar(im, fraction=0.046, pad=0.04, orientation="vertical") plt.show() # %% [markdown] @@ -384,25 +454,25 @@ def __call__( # %% [markdown] # ## Negative Log Predictive Densities -# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data, +# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data, # # $$ # \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right) # $$ # -# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. +# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. # %% -#ensure testing data alternates between x0 and x1 components -Vel_Query = jnp.column_stack((Vel_Test[0],Vel_Test[1])).flatten() +# ensure testing data alternates between x0 and x1 components +Vel_Query = jnp.column_stack((Vel_Test[0], Vel_Test[1])).flatten() -NormalVel= tfp.substrates.jax.distributions.Normal( - loc = VelocityMean, - scale = VelocityStd, +NormalVel = tfp.substrates.jax.distributions.Normal( + loc=VelocityMean, + scale=VelocityStd, ) -NormalHelm= tfp.substrates.jax.distributions.Normal( - loc = HelmholtzMean, - scale = HelmholtzStd, +NormalHelm = tfp.substrates.jax.distributions.Normal( + loc=HelmholtzMean, + scale=HelmholtzStd, ) NLPDVel = -jnp.sum(NormalVel.log_prob(Vel_Query)) @@ -414,7 +484,7 @@ def __call__( # %% [markdown] -# +# # ## Footnote # Kernels for vector valued functions have been studied in the literature, see [Alvarez et. al, (2012)](https://doi.org/10.48550/arXiv.1106.6251) # ## System Configuration From a723952e63747158aae547bccbc623ac21310c3e Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Wed, 9 Aug 2023 13:29:15 +0100 Subject: [PATCH 08/76] Add search space class for BayesOpt Added an `AbstractSearchSpace` abstract base class for the BayesOpt library, as well as a concrete implementation in the form of a `ContinuousSearchSpace` class. Tests have also been added. --- gpjax/bayes_opt/__init__.py | 19 ++ gpjax/bayes_opt/search_space.py | 98 ++++++++++ gpjax/kernels/__init__.py | 5 +- gpjax/kernels/non_euclidean/__init__.py | 2 +- gpjax/kernels/non_euclidean/categorical.py | 12 +- tests/test_bayes_opt/__init__.py | 0 tests/test_bayes_opt/test_search_space.py | 204 +++++++++++++++++++++ tests/test_dataset.py | 4 +- tests/test_kernels/test_non_euclidean.py | 7 +- 9 files changed, 341 insertions(+), 10 deletions(-) create mode 100644 gpjax/bayes_opt/__init__.py create mode 100644 gpjax/bayes_opt/search_space.py create mode 100644 tests/test_bayes_opt/__init__.py create mode 100644 tests/test_bayes_opt/test_search_space.py diff --git a/gpjax/bayes_opt/__init__.py b/gpjax/bayes_opt/__init__.py new file mode 100644 index 000000000..5937ffd33 --- /dev/null +++ b/gpjax/bayes_opt/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from gpjax.bayes_opt import search_space + +__all__ = [ + "search_space", +] diff --git a/gpjax/bayes_opt/search_space.py b/gpjax/bayes_opt/search_space.py new file mode 100644 index 000000000..1551aec4b --- /dev/null +++ b/gpjax/bayes_opt/search_space.py @@ -0,0 +1,98 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import dataclass + +from jaxtyping import Float +import tensorflow_probability.substrates.jax as tfp + +from gpjax.typing import ( + Array, + KeyArray, +) + + +@dataclass +class AbstractSearchSpace(ABC): + """The `AbstractSearchSpace` class is an abstract base class for + search spaces, which are used to bound the domain of functions being optimised. + """ + + @abstractmethod + def sample(self, num_points: int, key: KeyArray) -> Float[Array, "N D"]: + """Sample points from the search space. + Args: + num_points (int): Number of points to be sampled from the search space. + key (KeyArray): JAX PRNG key. + Returns: + Float[Array, "N D"]: `num_points` points sampled from the search space. + """ + raise NotImplementedError + + @property + @abstractmethod + def dimensionality(self) -> int: + """Dimensionality of the search space. + Returns: + int: Dimensionality of the search space. + """ + raise NotImplementedError + + +@dataclass +class ContinuousSearchSpace(AbstractSearchSpace): + """The `ContinuousSearchSpace` class is used to bound the domain of continuous real functions of dimension $`D`$.""" + + lower_bounds: Float[Array, " D"] + upper_bounds: Float[Array, " D"] + + def __post_init__(self): + if self.lower_bounds.shape != self.upper_bounds.shape: + raise ValueError("Lower and upper bounds must have the same shape.") + if self.lower_bounds.shape[0] == 0: + raise ValueError("Lower and upper bounds cannot be empty") + if not (self.lower_bounds < self.upper_bounds).all(): + raise ValueError("Lower bounds must be less than upper bounds.") + + @property + def dimensionality(self) -> int: + return self.lower_bounds.shape[0] + + def sample(self, num_points: int, key: KeyArray) -> Float[Array, "N D"]: + """Sample points from the search space using a Halton sequence. + + Note that a single key generates a single sequence so, for instance, if one + generates a sequence of length 5 and a sequence of length 10 with the same key + then the former will be a prefix of the latter. + + Args: + num_points (int): Number of points to be sampled from the search space. + key (KeyArray): JAX PRNG key. + Returns: + Float[Array, "N D"]: `num_points` points sampled using the Halton sequence + from the search space. + """ + if num_points <= 0: + raise ValueError("Number of points must be greater than 0.") + + initial_sample = tfp.mcmc.sample_halton_sequence( + dim=self.dimensionality, num_results=num_points, seed=key + ) + return ( + self.lower_bounds + (self.upper_bounds - self.lower_bounds) * initial_sample + ) diff --git a/gpjax/kernels/__init__.py b/gpjax/kernels/__init__.py index 178aeba17..89809adaf 100644 --- a/gpjax/kernels/__init__.py +++ b/gpjax/kernels/__init__.py @@ -27,7 +27,10 @@ DiagonalKernelComputation, EigenKernelComputation, ) -from gpjax.kernels.non_euclidean import GraphKernel, CatKernel +from gpjax.kernels.non_euclidean import ( + CatKernel, + GraphKernel, +) from gpjax.kernels.nonstationary import ( ArcCosine, Linear, diff --git a/gpjax/kernels/non_euclidean/__init__.py b/gpjax/kernels/non_euclidean/__init__.py index 1289f1d60..ee45287b0 100644 --- a/gpjax/kernels/non_euclidean/__init__.py +++ b/gpjax/kernels/non_euclidean/__init__.py @@ -13,7 +13,7 @@ # limitations under the License. # ============================================================================== -from gpjax.kernels.non_euclidean.graph import GraphKernel from gpjax.kernels.non_euclidean.categorical import CatKernel +from gpjax.kernels.non_euclidean.graph import GraphKernel __all__ = ["GraphKernel", "CatKernel"] diff --git a/gpjax/kernels/non_euclidean/categorical.py b/gpjax/kernels/non_euclidean/categorical.py index e0f1e610b..1d376956f 100644 --- a/gpjax/kernels/non_euclidean/categorical.py +++ b/gpjax/kernels/non_euclidean/categorical.py @@ -15,9 +15,16 @@ from dataclasses import dataclass -from typing import NamedTuple, Union +from typing import ( + NamedTuple, + Union, +) + import jax.numpy as jnp -from jaxtyping import Float, Int +from jaxtyping import ( + Float, + Int, +) import tensorflow_probability.substrates.jax as tfp from gpjax.base import ( @@ -25,7 +32,6 @@ static_field, ) from gpjax.kernels.base import AbstractKernel - from gpjax.typing import ( Array, ScalarInt, diff --git a/tests/test_bayes_opt/__init__.py b/tests/test_bayes_opt/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_bayes_opt/test_search_space.py b/tests/test_bayes_opt/test_search_space.py new file mode 100644 index 000000000..2d733df46 --- /dev/null +++ b/tests/test_bayes_opt/test_search_space.py @@ -0,0 +1,204 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from jax.config import config +import jax.numpy as jnp +import jax.random as jr +from jaxtyping import ( + Array, + Float, +) +import pytest + +from gpjax.bayes_opt.search_space import ( + AbstractSearchSpace, + ContinuousSearchSpace, +) + +config.update("jax_enable_x64", True) + + +def test_abstract_search_space(): + with pytest.raises(TypeError): + AbstractSearchSpace() + + +def test_continuous_search_space_empty_bounds(): + with pytest.raises(ValueError): + ContinuousSearchSpace(lower_bounds=jnp.array([]), upper_bounds=jnp.array([])) + + +@pytest.mark.parametrize( + "lower_bounds, upper_bounds", + [ + (jnp.array([0.0]), jnp.array([1.0, 1.0])), + (jnp.array([0.0, 0.0]), jnp.array([1.0])), + ], +) +def test_continous_search_space_bounds_shape_consistency( + lower_bounds: Float[Array, " D"], upper_bounds: Float[Array, " D"] +): + with pytest.raises(ValueError): + ContinuousSearchSpace(lower_bounds=lower_bounds, upper_bounds=upper_bounds) + + +@pytest.mark.parametrize( + "lower_bounds, upper_bounds", + [ + (jnp.array([1.0]), jnp.array([0.0])), + (jnp.array([1.0, 1.0]), jnp.array([0.0, 2.0])), + (jnp.array([1.0, 1.0]), jnp.array([2.0, 0.0])), + ], +) +def test_continuous_search_space_bounds_values_consistency( + lower_bounds: Float[Array, " D"], upper_bounds: Float[Array, " D"] +): + with pytest.raises(ValueError): + ContinuousSearchSpace(lower_bounds=lower_bounds, upper_bounds=upper_bounds) + + +@pytest.mark.parametrize( + "continuous_search_space, dimensionality", + [ + (ContinuousSearchSpace(jnp.array([0.0]), jnp.array([1.0])), 1), + (ContinuousSearchSpace(jnp.array([0.0, 0.0]), jnp.array([1.0, 1.0])), 2), + ( + ContinuousSearchSpace( + jnp.array([0.0, 0.0, 0.0]), jnp.array([1.0, 1.0, 1.0]) + ), + 3, + ), + ], +) +def test_continuous_search_space_dimensionality( + continuous_search_space: ContinuousSearchSpace, dimensionality: int +): + assert continuous_search_space.dimensionality == dimensionality + + +@pytest.mark.parametrize( + "continuous_search_space", + [ + ContinuousSearchSpace(jnp.array([0.0]), jnp.array([1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0]), jnp.array([1.0, 1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0, 0.0]), jnp.array([1.0, 1.0, 1.0])), + ], +) +@pytest.mark.parametrize("num_points", [0, -1]) +def test_continous_search_space_invalid_sample_num_points( + continuous_search_space: ContinuousSearchSpace, num_points: int +): + with pytest.raises(ValueError): + continuous_search_space.sample(num_points=num_points, key=jr.PRNGKey(42)) + + +@pytest.mark.parametrize( + "continuous_search_space, dimensionality", + [ + (ContinuousSearchSpace(jnp.array([0.0]), jnp.array([1.0])), 1), + (ContinuousSearchSpace(jnp.array([0.0, 0.0]), jnp.array([1.0, 1.0])), 2), + ( + ContinuousSearchSpace( + jnp.array([0.0, 0.0, 0.0]), jnp.array([1.0, 1.0, 1.0]) + ), + 3, + ), + ], +) +@pytest.mark.parametrize("num_points", [1, 5, 50]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continuous_search_space_sample_shape( + continuous_search_space: ContinuousSearchSpace, dimensionality: int, num_points: int +): + samples = continuous_search_space.sample(num_points=num_points, key=jr.PRNGKey(42)) + assert samples.shape[0] == num_points + assert samples.shape[1] == dimensionality + + +@pytest.mark.parametrize( + "continuous_search_space", + [ + ContinuousSearchSpace(jnp.array([0.0]), jnp.array([1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0]), jnp.array([1.0, 1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0, 0.0]), jnp.array([1.0, 1.0, 1.0])), + ], +) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(5)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continous_search_space_sample_same_key_same_samples( + continuous_search_space: ContinuousSearchSpace, key: jr.PRNGKey +): + sample_one = continuous_search_space.sample(num_points=100, key=key) + sample_two = continuous_search_space.sample(num_points=100, key=key) + assert jnp.array_equal(sample_one, sample_two) + + +@pytest.mark.parametrize( + "continuous_search_space", + [ + ContinuousSearchSpace(jnp.array([0.0]), jnp.array([1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0]), jnp.array([1.0, 1.0])), + ContinuousSearchSpace(jnp.array([0.0, 0.0, 0.0]), jnp.array([1.0, 1.0, 1.0])), + ], +) +@pytest.mark.parametrize( + "key_one, key_two", + [(jr.PRNGKey(42), jr.PRNGKey(5)), (jr.PRNGKey(1), jr.PRNGKey(2))], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continuous_search_space_different_keys_different_samples( + continuous_search_space: ContinuousSearchSpace, + key_one: jr.PRNGKey, + key_two: jr.PRNGKey, +): + sample_one = continuous_search_space.sample(num_points=100, key=key_one) + sample_two = continuous_search_space.sample(num_points=100, key=key_two) + assert not jnp.array_equal(sample_one, sample_two) + + +@pytest.mark.parametrize( + "continuous_search_space", + [ + ContinuousSearchSpace( + lower_bounds=jnp.array([0.0]), upper_bounds=jnp.array([1.0]) + ), + ContinuousSearchSpace( + lower_bounds=jnp.array([0.0, 0.0]), upper_bounds=jnp.array([1.0, 2.0]) + ), + ContinuousSearchSpace( + lower_bounds=jnp.array([0.0, 1.0]), upper_bounds=jnp.array([2.0, 2.0]) + ), + ContinuousSearchSpace( + lower_bounds=jnp.array([2.4, 1.7, 4.9]), + upper_bounds=jnp.array([5.6, 1.8, 6.0]), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continuous_search_space_valid_sample_ranges( + continuous_search_space: ContinuousSearchSpace, +): + samples = continuous_search_space.sample(num_points=100, key=jr.PRNGKey(42)) + for i in range(continuous_search_space.dimensionality): + assert jnp.all(samples[:, i] >= continuous_search_space.lower_bounds[i]) + assert jnp.all(samples[:, i] <= continuous_search_space.upper_bounds[i]) diff --git a/tests/test_dataset.py b/tests/test_dataset.py index 38c277528..af119a5ac 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -185,9 +185,7 @@ def test_precision_warning( if prec_y != jnp.float64: expected_warnings += 1 - with pytest.warns( - UserWarning, match=".* is not of type float64.*" - ) as record: + with pytest.warns(UserWarning, match=".* is not of type float64.*") as record: Dataset(X=x, y=y) assert len(record) == expected_warnings diff --git a/tests/test_kernels/test_non_euclidean.py b/tests/test_kernels/test_non_euclidean.py index bdcb91b98..3ce5722b4 100644 --- a/tests/test_kernels/test_non_euclidean.py +++ b/tests/test_kernels/test_non_euclidean.py @@ -12,11 +12,14 @@ from jax.config import config import jax.numpy as jnp +import jax.random as jr import networkx as nx -from gpjax.kernels.non_euclidean import GraphKernel, CatKernel +from gpjax.kernels.non_euclidean import ( + CatKernel, + GraphKernel, +) from gpjax.linops import identity -import jax.random as jr # # Enable Float64 for more stable matrix inversions. config.update("jax_enable_x64", True) From d487bd68dd66e7a111f89f92c0f2925777bf2c95 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Wed, 9 Aug 2023 16:45:47 +0100 Subject: [PATCH 09/76] Minor additions to search space - Check that `lower_bounds` and `upper_bounds` are of same dtype. - Allow some dimensions of `lower_bounds` to be equal to `upper_bounds` as users may wish to keep certain dimensions fixed. --- gpjax/bayes_opt/search_space.py | 10 ++++------ tests/test_bayes_opt/test_search_space.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/gpjax/bayes_opt/search_space.py b/gpjax/bayes_opt/search_space.py index 1551aec4b..18345c207 100644 --- a/gpjax/bayes_opt/search_space.py +++ b/gpjax/bayes_opt/search_space.py @@ -30,7 +30,7 @@ @dataclass class AbstractSearchSpace(ABC): """The `AbstractSearchSpace` class is an abstract base class for - search spaces, which are used to bound the domain of functions being optimised. + search spaces, which are used to define domains for sampling and optimisation functionality in GPJax. """ @abstractmethod @@ -62,11 +62,13 @@ class ContinuousSearchSpace(AbstractSearchSpace): upper_bounds: Float[Array, " D"] def __post_init__(self): + if not self.lower_bounds.dtype == self.upper_bounds.dtype: + raise ValueError("Lower and upper bounds must have the same dtype.") if self.lower_bounds.shape != self.upper_bounds.shape: raise ValueError("Lower and upper bounds must have the same shape.") if self.lower_bounds.shape[0] == 0: raise ValueError("Lower and upper bounds cannot be empty") - if not (self.lower_bounds < self.upper_bounds).all(): + if not (self.lower_bounds <= self.upper_bounds).all(): raise ValueError("Lower bounds must be less than upper bounds.") @property @@ -76,10 +78,6 @@ def dimensionality(self) -> int: def sample(self, num_points: int, key: KeyArray) -> Float[Array, "N D"]: """Sample points from the search space using a Halton sequence. - Note that a single key generates a single sequence so, for instance, if one - generates a sequence of length 5 and a sequence of length 10 with the same key - then the former will be a prefix of the latter. - Args: num_points (int): Number of points to be sampled from the search space. key (KeyArray): JAX PRNG key. diff --git a/tests/test_bayes_opt/test_search_space.py b/tests/test_bayes_opt/test_search_space.py index 2d733df46..b63d43578 100644 --- a/tests/test_bayes_opt/test_search_space.py +++ b/tests/test_bayes_opt/test_search_space.py @@ -40,6 +40,20 @@ def test_continuous_search_space_empty_bounds(): ContinuousSearchSpace(lower_bounds=jnp.array([]), upper_bounds=jnp.array([])) +@pytest.mark.parametrize( + "lower_bounds, upper_bounds", + [ + (jnp.array([0.0], dtype=jnp.float64), jnp.array([1.0], jnp.float32)), + (jnp.array([0.0], dtype=jnp.float32), jnp.array([1.0], jnp.float64)), + ], +) +def test_continuous_search_space_dtype_consistency( + lower_bounds: Float[Array, " D"], upper_bounds: Float[Array, " D"] +): + with pytest.raises(ValueError): + ContinuousSearchSpace(lower_bounds=lower_bounds, upper_bounds=upper_bounds) + + @pytest.mark.parametrize( "lower_bounds, upper_bounds", [ From b3688b5c72ae965f48cd33963c3e6c76383c73b0 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 7 Jul 2023 09:38:41 +0100 Subject: [PATCH 10/76] Fix bug in zero mean function and add test --- docs/examples/test.ipynb | 302 +++++++++++++++++++++++++++++++++++ gpjax/kernels/__init__.py | 7 +- gpjax/mean_functions.py | 12 +- tests/test_mean_functions.py | 45 ++++++ 4 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 docs/examples/test.ipynb diff --git a/docs/examples/test.ipynb b/docs/examples/test.ipynb new file mode 100644 index 000000000..969abc365 --- /dev/null +++ b/docs/examples/test.ipynb @@ -0,0 +1,302 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Enable Float64 for more stable matrix inversions.\n", + "from jax.config import config\n", + "\n", + "config.update(\"jax_enable_x64\", True)\n", + "\n", + "from jax import jit\n", + "import jax.numpy as jnp\n", + "import jax.random as jr\n", + "from jaxtyping import install_import_hook\n", + "import matplotlib as mpl\n", + "import matplotlib.pyplot as plt\n", + "import optax as ox\n", + "from docs.examples.utils import clean_legend\n", + "\n", + "with install_import_hook(\"gpjax\", \"beartype.beartype\"):\n", + " import gpjax as gpx\n", + "\n", + "key = jr.PRNGKey(123)\n", + "plt.style.use(\"./gpjax.mplstyle\")\n", + "cols = mpl.rcParams[\"axes.prop_cycle\"].by_key()[\"color\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "x = jr.uniform(key=key, minval=0, maxval=1, shape=(20, 1))\n", + "y = jnp.full((20, 1), 50, dtype=jnp.float64)\n", + "D = gpx.Dataset(X=x, y=y)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.scatter(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "kernel = gpx.kernels.Matern52()\n", + "meanf = gpx.mean_functions.Zero()\n", + "prior = gpx.Prior(mean_function=meanf, kernel=kernel)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "prior_dist = prior.predict(x)\n", + "prior_mean = prior_dist.mean()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "likelihood = gpx.Gaussian(num_datapoints=D.n)\n", + "likelihood = gpx.Gaussian(\n", + " num_datapoints=D.n, obs_noise=jnp.array(1e-6)\n", + ") # Our function is noise-free, so we set the observation noise to a very small value\n", + "likelihood = likelihood.replace_trainable(obs_noise=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "posterior = prior * likelihood" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Array(1719.45465439, dtype=float64)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "negative_mll = gpx.objectives.ConjugateMLL(negative=True)\n", + "negative_mll(posterior, train_data=D)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "negative_mll = jit(negative_mll)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f0219c477fa241108aa2ce30c9000297", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/2000 [00:00" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "xtest = jnp.linspace(0, 1, 100).reshape(-1, 1)\n", + "\n", + "latent_dist = opt_posterior.predict(xtest, train_data=D)\n", + "predictive_dist = opt_posterior.likelihood(latent_dist)\n", + "\n", + "predictive_mean = predictive_dist.mean()\n", + "predictive_std = predictive_dist.stddev()\n", + "\n", + "fig, ax = plt.subplots(figsize=(7.5, 2.5))\n", + "ax.plot(x, y, \"x\", label=\"Observations\", color=cols[0], alpha=0.5)\n", + "ax.fill_between(\n", + " xtest.squeeze(),\n", + " predictive_mean - 2 * predictive_std,\n", + " predictive_mean + 2 * predictive_std,\n", + " alpha=0.2,\n", + " label=\"Two sigma\",\n", + " color=cols[1],\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean - 2 * predictive_std,\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + " color=cols[1],\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean + 2 * predictive_std,\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + " color=cols[1],\n", + ")\n", + "# ax.plot(\n", + "# xtest, ytest, label=\"Latent function\", color=cols[0], linestyle=\"--\", linewidth=2\n", + "# )\n", + "ax.plot(xtest, predictive_mean, label=\"Predictive mean\", color=cols[1])\n", + "ax.legend(loc=\"center left\", bbox_to_anchor=(0.975, 0.5))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/gpjax/kernels/__init__.py b/gpjax/kernels/__init__.py index 178aeba17..3e01404e9 100644 --- a/gpjax/kernels/__init__.py +++ b/gpjax/kernels/__init__.py @@ -17,6 +17,7 @@ from gpjax.kernels.approximations import RFF from gpjax.kernels.base import ( AbstractKernel, + Constant, ProductKernel, SumKernel, ) @@ -27,7 +28,10 @@ DiagonalKernelComputation, EigenKernelComputation, ) -from gpjax.kernels.non_euclidean import GraphKernel, CatKernel +from gpjax.kernels.non_euclidean import ( + CatKernel, + GraphKernel, +) from gpjax.kernels.nonstationary import ( ArcCosine, Linear, @@ -47,6 +51,7 @@ __all__ = [ "AbstractKernel", "ArcCosine", + "Constant", "RBF", "GraphKernel", "CatKernel", diff --git a/gpjax/mean_functions.py b/gpjax/mean_functions.py index 13e6fd7b1..61d72519c 100644 --- a/gpjax/mean_functions.py +++ b/gpjax/mean_functions.py @@ -150,6 +150,17 @@ def __call__(self, x: Num[Array, "N D"]) -> Float[Array, "N 1"]: return jnp.ones((x.shape[0], 1)) * self.constant +@dataclasses.dataclass +class Zero(Constant): + r"""Zero mean function. + + The zero mean function. This function returns a zero scalar value for all + inputs. Unlike the Constant mean function, the constant scalar zero is fixed, and + cannot be treated as a model hyperparameter and learned during training. + """ + constant: Float[Array, "1"] = static_field(jnp.array([0.0]), init=False) + + @dataclasses.dataclass class CombinationMeanFunction(AbstractMeanFunction): r"""A base class for products or sums of AbstractMeanFunctions.""" @@ -199,4 +210,3 @@ def __call__(self, x: Num[Array, "N D"]) -> Float[Array, "N 1"]: ProductMeanFunction = partial( CombinationMeanFunction, operator=partial(jnp.sum, axis=0) ) -Zero = partial(Constant, constant=jnp.array([0.0])) diff --git a/tests/test_mean_functions.py b/tests/test_mean_functions.py index b4740b15d..a397e7381 100644 --- a/tests/test_mean_functions.py +++ b/tests/test_mean_functions.py @@ -1,13 +1,24 @@ +# Enable Float64 for more stable matrix inversions. +from jax.config import config + +config.update("jax_enable_x64", True) + + +from jax import jit import jax.numpy as jnp +import jax.random as jr from jaxtyping import ( Array, Float, ) +import optax as ox import pytest +import gpjax as gpx from gpjax.mean_functions import ( AbstractMeanFunction, Constant, + Zero, ) @@ -40,3 +51,37 @@ def test_constant(constant: Float[Array, " Q"]) -> None: assert ( mf(jnp.array([[1.0, 2.0], [3.0, 4.0]])) == jnp.array([constant, constant]) ).all() + + +def test_zero_mean_remains_zero() -> None: + key = jr.PRNGKey(123) + + x = jr.uniform(key=key, minval=0, maxval=1, shape=(20, 1)) + y = jnp.full((20, 1), 50, dtype=jnp.float64) # Dataset with non-zero mean + D = gpx.Dataset(X=x, y=y) + + kernel = gpx.kernels.Constant(constant=jnp.array(0.0)) + kernel = kernel.replace_trainable( + constant=False + ) # Prevent kernel from modelling non-zero mean + meanf = Zero() + prior = gpx.Prior(mean_function=meanf, kernel=kernel) + likelihood = gpx.Gaussian(num_datapoints=D.n, obs_noise=jnp.array(1e-6)) + likelihood = likelihood.replace_trainable(obs_noise=False) + posterior = prior * likelihood + + negative_mll = gpx.objectives.ConjugateMLL(negative=True) + negative_mll(posterior, train_data=D) + negative_mll = jit(negative_mll) + + opt_posterior, history = gpx.fit( + model=posterior, + objective=negative_mll, + train_data=D, + optim=ox.adam(learning_rate=0.5), + num_iters=1000, + safe=True, + key=key, + ) + + assert opt_posterior.prior.mean_function.constant == 0.0 From ffb57d8673f9405b77a0c20f8bc9129a39298bee Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Thu, 10 Aug 2023 13:16:01 +0100 Subject: [PATCH 11/76] Remove accidentally added notebook --- docs/examples/test.ipynb | 302 --------------------------------------- 1 file changed, 302 deletions(-) delete mode 100644 docs/examples/test.ipynb diff --git a/docs/examples/test.ipynb b/docs/examples/test.ipynb deleted file mode 100644 index 969abc365..000000000 --- a/docs/examples/test.ipynb +++ /dev/null @@ -1,302 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# Enable Float64 for more stable matrix inversions.\n", - "from jax.config import config\n", - "\n", - "config.update(\"jax_enable_x64\", True)\n", - "\n", - "from jax import jit\n", - "import jax.numpy as jnp\n", - "import jax.random as jr\n", - "from jaxtyping import install_import_hook\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import optax as ox\n", - "from docs.examples.utils import clean_legend\n", - "\n", - "with install_import_hook(\"gpjax\", \"beartype.beartype\"):\n", - " import gpjax as gpx\n", - "\n", - "key = jr.PRNGKey(123)\n", - "plt.style.use(\"./gpjax.mplstyle\")\n", - "cols = mpl.rcParams[\"axes.prop_cycle\"].by_key()[\"color\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "x = jr.uniform(key=key, minval=0, maxval=1, shape=(20, 1))\n", - "y = jnp.full((20, 1), 50, dtype=jnp.float64)\n", - "D = gpx.Dataset(X=x, y=y)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.scatter(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "kernel = gpx.kernels.Matern52()\n", - "meanf = gpx.mean_functions.Zero()\n", - "prior = gpx.Prior(mean_function=meanf, kernel=kernel)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "prior_dist = prior.predict(x)\n", - "prior_mean = prior_dist.mean()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "likelihood = gpx.Gaussian(num_datapoints=D.n)\n", - "likelihood = gpx.Gaussian(\n", - " num_datapoints=D.n, obs_noise=jnp.array(1e-6)\n", - ") # Our function is noise-free, so we set the observation noise to a very small value\n", - "likelihood = likelihood.replace_trainable(obs_noise=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "posterior = prior * likelihood" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Array(1719.45465439, dtype=float64)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "negative_mll = gpx.objectives.ConjugateMLL(negative=True)\n", - "negative_mll(posterior, train_data=D)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "negative_mll = jit(negative_mll)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "f0219c477fa241108aa2ce30c9000297", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/2000 [00:00" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "xtest = jnp.linspace(0, 1, 100).reshape(-1, 1)\n", - "\n", - "latent_dist = opt_posterior.predict(xtest, train_data=D)\n", - "predictive_dist = opt_posterior.likelihood(latent_dist)\n", - "\n", - "predictive_mean = predictive_dist.mean()\n", - "predictive_std = predictive_dist.stddev()\n", - "\n", - "fig, ax = plt.subplots(figsize=(7.5, 2.5))\n", - "ax.plot(x, y, \"x\", label=\"Observations\", color=cols[0], alpha=0.5)\n", - "ax.fill_between(\n", - " xtest.squeeze(),\n", - " predictive_mean - 2 * predictive_std,\n", - " predictive_mean + 2 * predictive_std,\n", - " alpha=0.2,\n", - " label=\"Two sigma\",\n", - " color=cols[1],\n", - ")\n", - "ax.plot(\n", - " xtest,\n", - " predictive_mean - 2 * predictive_std,\n", - " linestyle=\"--\",\n", - " linewidth=1,\n", - " color=cols[1],\n", - ")\n", - "ax.plot(\n", - " xtest,\n", - " predictive_mean + 2 * predictive_std,\n", - " linestyle=\"--\",\n", - " linewidth=1,\n", - " color=cols[1],\n", - ")\n", - "# ax.plot(\n", - "# xtest, ytest, label=\"Latent function\", color=cols[0], linestyle=\"--\", linewidth=2\n", - "# )\n", - "ax.plot(xtest, predictive_mean, label=\"Predictive mean\", color=cols[1])\n", - "ax.legend(loc=\"center left\", bbox_to_anchor=(0.975, 0.5))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.2" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} From cdb0f0346c62d23fa391738290d9bae32f632a81 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Thu, 10 Aug 2023 13:54:22 +0100 Subject: [PATCH 12/76] Add additional tests for zero mean --- tests/test_mean_functions.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_mean_functions.py b/tests/test_mean_functions.py index a397e7381..105e3a629 100644 --- a/tests/test_mean_functions.py +++ b/tests/test_mean_functions.py @@ -4,6 +4,7 @@ config.update("jax_enable_x64", True) +import jax from jax import jit import jax.numpy as jnp import jax.random as jr @@ -85,3 +86,14 @@ def test_zero_mean_remains_zero() -> None: ) assert opt_posterior.prior.mean_function.constant == 0.0 + + +def test_zero_mean_pytree_no_leaves(): + zero_mean = Zero() + leaves = jax.tree_util.tree_leaves(zero_mean) + assert len(leaves) == 0 + + +def test_initialising_zero_mean_with_constant_raises_error(): + with pytest.raises(TypeError): + Zero(constant=jnp.array([1.0])) From a3579bb1d2ac8bd7064e3c5eabafc35768af4048 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Thu, 10 Aug 2023 21:36:38 +0100 Subject: [PATCH 13/76] Add classes for forming acquisition functions Added an `AbstractAcquisitionFunctionBuilder` abstract base class for forming acquisition functions, and added `ThompsonSampling` as a concrete example. Unit tests have also been added. Also renamed the `bayes_opt` module to `decision_making` to reflect the fact that we aim for this module to support general sequential decision making, and not solely Bayes opt. --- .../__init__.py | 2 +- .../acquisition_functions/__init__.py | 27 +++ .../acquisition_functions/base.py | 57 +++++ .../thompson_sampling.py | 68 ++++++ .../search_space.py | 0 gpjax/decision_making/utils.py | 17 ++ .../__init__.py | 0 .../test_acquisition_functions/__init__.py | 0 .../test_acquisition_functions/test_base.py | 28 +++ .../test_thompson_sampling.py | 218 ++++++++++++++++++ .../test_search_space.py | 2 +- 11 files changed, 417 insertions(+), 2 deletions(-) rename gpjax/{bayes_opt => decision_making}/__init__.py (94%) create mode 100644 gpjax/decision_making/acquisition_functions/__init__.py create mode 100644 gpjax/decision_making/acquisition_functions/base.py create mode 100644 gpjax/decision_making/acquisition_functions/thompson_sampling.py rename gpjax/{bayes_opt => decision_making}/search_space.py (100%) create mode 100644 gpjax/decision_making/utils.py rename tests/{test_bayes_opt => test_decision_making}/__init__.py (100%) create mode 100644 tests/test_decision_making/test_acquisition_functions/__init__.py create mode 100644 tests/test_decision_making/test_acquisition_functions/test_base.py create mode 100644 tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py rename tests/{test_bayes_opt => test_decision_making}/test_search_space.py (99%) diff --git a/gpjax/bayes_opt/__init__.py b/gpjax/decision_making/__init__.py similarity index 94% rename from gpjax/bayes_opt/__init__.py rename to gpjax/decision_making/__init__.py index 5937ffd33..97e59c17a 100644 --- a/gpjax/bayes_opt/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from gpjax.bayes_opt import search_space +from gpjax.decision_making import search_space __all__ = [ "search_space", diff --git a/gpjax/decision_making/acquisition_functions/__init__.py b/gpjax/decision_making/acquisition_functions/__init__.py new file mode 100644 index 000000000..9c986fff6 --- /dev/null +++ b/gpjax/decision_making/acquisition_functions/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from gpjax.decision_making.acquisition_functions.base import ( + AbstractAcquisitionFunctionBuilder, + AcquisitionFunction, +) +from gpjax.decision_making.acquisition_functions.thompson_sampling import ( + ThompsonSampling, +) + +__all__ = [ + "AcquisitionFunction", + "AbstractAcquisitionFunctionBuilder", + "ThompsonSampling", +] diff --git a/gpjax/decision_making/acquisition_functions/base.py b/gpjax/decision_making/acquisition_functions/base.py new file mode 100644 index 000000000..9bd031414 --- /dev/null +++ b/gpjax/decision_making/acquisition_functions/base.py @@ -0,0 +1,57 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import dataclass +from typing import ( + Callable, + Mapping, + Optional, +) + +from gpjax.dataset import Dataset +from gpjax.gps import AbstractPosterior +from gpjax.typing import ( + Array, + Float, + KeyArray, +) + +AcquisitionFunction = Callable[[Float[Array, "N D"]], Float[Array, "N 1"]] +""" +Type alias for acquisition functions, which take an array of points of shape $`[N, D]`$ +and return the value of the acquisition function at each point in an array of shape $`[N, 1]`$. +""" + + +@dataclass +class AbstractAcquisitionFunctionBuilder(ABC): + """ + Abstract class for building acquisition functions. + """ + + @abstractmethod + def build_acquisition_function( + self, + posteriors: Mapping[str, AbstractPosterior], + datasets: Optional[Mapping[str, Dataset]], + key: KeyArray, + ) -> AcquisitionFunction: + """ + Build an `AcquisitionFunction` from a set of posteriors and datasets. + """ + raise NotImplementedError diff --git a/gpjax/decision_making/acquisition_functions/thompson_sampling.py b/gpjax/decision_making/acquisition_functions/thompson_sampling.py new file mode 100644 index 000000000..c13e64ab3 --- /dev/null +++ b/gpjax/decision_making/acquisition_functions/thompson_sampling.py @@ -0,0 +1,68 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from dataclasses import dataclass +from typing import Mapping + +from gpjax.dataset import Dataset +from gpjax.decision_making.acquisition_functions.base import ( + AbstractAcquisitionFunctionBuilder, + AcquisitionFunction, +) +from gpjax.decision_making.utils import OBJECTIVE +from gpjax.gps import ConjugatePosterior +from gpjax.typing import KeyArray + + +@dataclass +class ThompsonSampling(AbstractAcquisitionFunctionBuilder): + """ + Form an acquisition function by drawing an approximate sample from the posterior, + using decoupled sampling as introduced in [Wilson et. al. (2020)](https://arxiv.org/abs/2002.09309). + """ + + num_rff_features: int = 500 + + def build_acquisition_function( + self, + posteriors: Mapping[str, ConjugatePosterior], + datasets: Mapping[str, Dataset], + key: KeyArray, + ) -> AcquisitionFunction: + if OBJECTIVE not in posteriors.keys(): + raise ValueError("Objective posterior not found in posteriors") + if OBJECTIVE not in datasets.keys(): + raise ValueError("Objective dataset not found in datasets") + if key is None: + raise ValueError( + "Key must be provided to draw an approximate sample from the posterior" + ) + + objective_posterior = posteriors[OBJECTIVE] + if not isinstance(objective_posterior, ConjugatePosterior): + raise ValueError( + "Objective posterior must be a ConjugatePosterior to draw an approximate sample." + ) + + objective_dataset = datasets[OBJECTIVE] + thompson_sample = objective_posterior.sample_approx( + num_samples=1, + train_data=objective_dataset, + key=key, + num_features=self.num_rff_features, + ) + + return lambda x: -1.0 * thompson_sample( + x + ) # Acquisition functions are *maximised* diff --git a/gpjax/bayes_opt/search_space.py b/gpjax/decision_making/search_space.py similarity index 100% rename from gpjax/bayes_opt/search_space.py rename to gpjax/decision_making/search_space.py diff --git a/gpjax/decision_making/utils.py b/gpjax/decision_making/utils.py new file mode 100644 index 000000000..91fa9a924 --- /dev/null +++ b/gpjax/decision_making/utils.py @@ -0,0 +1,17 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from beartype.typing import Final + +OBJECTIVE: Final[str] = "OBJECTIVE" diff --git a/tests/test_bayes_opt/__init__.py b/tests/test_decision_making/__init__.py similarity index 100% rename from tests/test_bayes_opt/__init__.py rename to tests/test_decision_making/__init__.py diff --git a/tests/test_decision_making/test_acquisition_functions/__init__.py b/tests/test_decision_making/test_acquisition_functions/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_decision_making/test_acquisition_functions/test_base.py b/tests/test_decision_making/test_acquisition_functions/test_base.py new file mode 100644 index 000000000..b71831ef3 --- /dev/null +++ b/tests/test_decision_making/test_acquisition_functions/test_base.py @@ -0,0 +1,28 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from jax.config import config +import pytest + +from gpjax.decision_making.acquisition_functions.base import ( + AbstractAcquisitionFunctionBuilder, +) + +config.update("jax_enable_x64", True) + + +def test_abstract_acquisition_function_builder(): + with pytest.raises(TypeError): + AbstractAcquisitionFunctionBuilder() diff --git a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py new file mode 100644 index 000000000..d69480ed3 --- /dev/null +++ b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py @@ -0,0 +1,218 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from beartype.typing import Callable +from jax.config import config +import jax.numpy as jnp +import jax.random as jr +from jaxtyping import ( + Array, + Float, +) +import pytest + +from gpjax.dataset import Dataset +from gpjax.decision_making.acquisition_functions.thompson_sampling import ( + ThompsonSampling, +) +from gpjax.decision_making.utils import OBJECTIVE +from gpjax.gps import ( + ConjugatePosterior, + NonConjugatePosterior, + Prior, +) +from gpjax.kernels import RBF +from gpjax.likelihoods import ( + Gaussian, + Poisson, +) +from gpjax.mean_functions import Zero + +config.update("jax_enable_x64", True) + + +def generate_dummy_1d_dataset() -> Dataset: + X = jr.uniform(key=jr.PRNGKey(42), minval=0.0, maxval=10.0, shape=(10, 1)) + y = jnp.sin(X) + X + 1.0 + 10 * jr.normal(jr.PRNGKey(42), shape=X.shape) + D = Dataset(X, y) + return D + + +def generate_dummy_2d_dataset() -> Dataset: + X = jr.uniform(key=jr.PRNGKey(42), minval=0.0, maxval=10.0, shape=(10, 2)) + X0 = X[:, 0].reshape(-1, 1) + X1 = X[:, 1].reshape(-1, 1) + y = ( + jnp.sin(X0) + + X1 + + X0**2 + + 1.0 + + 10 * jr.normal(jr.PRNGKey(42), shape=X0.shape) + ) + D = Dataset(X, y) + return D + + +def generate_dummy_1d_test_X(num_test_points: int) -> Float[Array, "N 1"]: + test_X = jnp.linspace(0.0, 10.0, num_test_points).reshape(-1, 1) + return test_X + + +def generate_dummy_2d_test_X(sqrt_num_test_points: int) -> Float[Array, "N 2"]: + test_X0 = jnp.linspace(0.0, 10.0, sqrt_num_test_points) + test_X1 = jnp.linspace(0.0, 10.0, sqrt_num_test_points) + test_X0, test_X1 = jnp.meshgrid(test_X0, test_X1) + test_X = jnp.column_stack((test_X0.ravel(), test_X1.ravel())) + return test_X + + +def generate_dummy_conjugate_posterior(dataset: Dataset) -> ConjugatePosterior: + kernel = RBF(lengthscale=jnp.ones(dataset.X.shape[1])) + mean_function = Zero() + prior = Prior(kernel=kernel, mean_function=mean_function) + likelihood = Gaussian(num_datapoints=dataset.n) + posterior = prior * likelihood + return posterior + + +def generate_dummy_non_conjugate_posterior(dataset: Dataset) -> NonConjugatePosterior: + kernel = RBF(lengthscale=jnp.ones(dataset.X.shape[1])) + mean_function = Zero() + prior = Prior(kernel=kernel, mean_function=mean_function) + likelihood = Poisson(num_datapoints=dataset.n) + posterior = prior * likelihood + return posterior + + +def test_thompson_sampling_no_objective_posterior_raises_error(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {"CONSTRAINT": posterior} + datasets = {OBJECTIVE: dataset} + key = jr.PRNGKey(42) + with pytest.raises(ValueError): + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + + +def test_thompson_sampling_no_objective_dataset_raises_error(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {"CONSTRAINT": dataset} + key = jr.PRNGKey(42) + with pytest.raises(ValueError): + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + + +def test_thompson_sampling_none_key_raises_error(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + with pytest.raises(ValueError): + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=None + ) + + +def test_thompson_sampling_non_conjugate_posterior_raises_error(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_non_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + key = jr.PRNGKey(42) + with pytest.raises(ValueError): + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + + +@pytest.mark.parametrize( + "dataset, dimensionality", + [(generate_dummy_1d_dataset(), 1), (generate_dummy_2d_dataset(), 2)], +) +@pytest.mark.parametrize("num_test_points", [49, 100]) +def test_thompson_sampling_acquisition_function_correct_shapes( + dataset: Dataset, dimensionality: int, num_test_points: int +): + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + key = jr.PRNGKey(42) + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_function = ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + if dimensionality == 1: + test_X = generate_dummy_1d_test_X(num_test_points) + elif dimensionality == 2: + test_X = generate_dummy_2d_test_X(int(jnp.sqrt(num_test_points))) + ts_acquisition_function_values = ts_acquisition_function(test_X) + assert ts_acquisition_function_values.shape == (num_test_points, 1) + + +def test_thompson_sampling_acquisition_function_same_key_same_function(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + key = jr.PRNGKey(42) + ts_acquisition_builder_one = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder_two = ThompsonSampling(num_rff_features=500) + ts_acquisition_function_one = ts_acquisition_builder_one.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + ts_acquisition_function_two = ts_acquisition_builder_two.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + test_X = jnp.linspace(0.0, 10.0, 100).reshape(-1, 1) + ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) + ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) + assert isinstance(ts_acquisition_function_one, Callable) + assert isinstance(ts_acquisition_function_two, Callable) + assert ( + ts_acquisition_function_one_values == ts_acquisition_function_two_values + ).all() + + +def test_thompson_sampling_acquisition_function_different_key_different_function(): + dataset = generate_dummy_1d_dataset() + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + key_one = jr.PRNGKey(42) + key_two = jr.PRNGKey(43) + ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_function_one = ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key_one + ) + ts_acquisition_function_two = ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key_two + ) + test_X = jnp.linspace(0.0, 10.0, 100).reshape(-1, 1) + ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) + ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) + assert isinstance(ts_acquisition_function_one, Callable) + assert isinstance(ts_acquisition_function_two, Callable) + assert not ( + ts_acquisition_function_one_values == ts_acquisition_function_two_values + ).all() diff --git a/tests/test_bayes_opt/test_search_space.py b/tests/test_decision_making/test_search_space.py similarity index 99% rename from tests/test_bayes_opt/test_search_space.py rename to tests/test_decision_making/test_search_space.py index b63d43578..85f814428 100644 --- a/tests/test_bayes_opt/test_search_space.py +++ b/tests/test_decision_making/test_search_space.py @@ -22,7 +22,7 @@ ) import pytest -from gpjax.bayes_opt.search_space import ( +from gpjax.decision_making.search_space import ( AbstractSearchSpace, ContinuousSearchSpace, ) From e2f645947a5d87f93f8d9489340f738bcc0e7758 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 11 Aug 2023 22:21:40 +0100 Subject: [PATCH 14/76] Add `AcquisitionMaximizer` functionality Added an `AbstractAcquisitionMaximizer` abstract base class for maximising acquisition functions, as well as a concrete `ContinuousAcquisitionMaximizer` implementation which uses L-BFGS-B for optimising continuous acquisition functions. Unit tests have also been added. --- .../decision_making/acquisition_maximizer.py | 127 ++++++++++ .../test_acquisition_maximizer.py | 216 ++++++++++++++++++ 2 files changed, 343 insertions(+) create mode 100644 gpjax/decision_making/acquisition_maximizer.py create mode 100644 tests/test_decision_making/test_acquisition_maximizer.py diff --git a/gpjax/decision_making/acquisition_maximizer.py b/gpjax/decision_making/acquisition_maximizer.py new file mode 100644 index 000000000..79a446220 --- /dev/null +++ b/gpjax/decision_making/acquisition_maximizer.py @@ -0,0 +1,127 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import dataclass + +import jax.numpy as jnp +from jaxopt import ScipyBoundedMinimize + +from gpjax.decision_making.acquisition_functions import AcquisitionFunction +from gpjax.decision_making.search_space import ( + AbstractSearchSpace, + ContinuousSearchSpace, +) +from gpjax.typing import ( + Array, + Float, + KeyArray, + ScalarFloat, +) + + +def _get_discrete_maximizer( + query_points: Float[Array, "N D"], acquisition_function: AcquisitionFunction +) -> Float[Array, "1 D"]: + """Get the point which maximises the acquisition function evaluated at a given set of points. + + Args: + query_points (Float[Array, "N D"]): Set of points at which to evaluate the + acquisition function. + acquisition_function (AcquisitionFunction): Acquisition function + to evaluate at `query_points`. + + Returns: + Float[Array, "1 D"]: Point in `query_points` which maximises the acquisition + function. + """ + acquisition_function_values = acquisition_function(query_points) + max_acquisition_function_value_idx = jnp.argmax( + acquisition_function_values, axis=0, keepdims=True + ) + best_sample_point = jnp.take_along_axis( + query_points, max_acquisition_function_value_idx, axis=0 + ) + return best_sample_point + + +@dataclass +class AbstractAcquisitionMaximizer(ABC): + """Abstract base class for acquisition function maximizers.""" + + @abstractmethod + def maximize( + self, + acquisition_function: AcquisitionFunction, + search_space: AbstractSearchSpace, + key: KeyArray, + ) -> Float[Array, "1 D"]: + """Maximize the given acquisition function over the search space provided. + + Args: + acquisition_function (AcquisitionFunction): Acquisition function to be + maximized. + search_space (AbstractSearchSpace): Search space over which to maximize + the acquisition function. + key (KeyArray): JAX PRNG key. + + Returns: + Float[Array, "1 D"]: Point at which the acquisition function is maximized. + """ + raise NotImplementedError + + +@dataclass +class ContinuousAcquisitionMaximizer(AbstractAcquisitionMaximizer): + """The `ContinuousAcquisitionMaximizer` class is used to maximize acquisition + functions over the continuous domain with L-BFGS-B. First we sample the acquisition + function at `num_initial_samples` points from the search space, and then we run + L-BFGS-B from the best of these initial points. + """ + + num_initial_samples: int + + def __post_init__(self): + if self.num_initial_samples < 1: + raise ValueError( + f"num_initial_samples must be greater than 0, got {self.num_initial_samples}." + ) + + def maximize( + self, + acquisition_function: AcquisitionFunction, + search_space: ContinuousSearchSpace, + key: KeyArray, + ) -> Float[Array, "1 D"]: + initial_sample_points = search_space.sample(self.num_initial_samples, key=key) + best_initial_sample_point = _get_discrete_maximizer( + initial_sample_points, acquisition_function + ) + + # Jaxopt minimizer requires a function which returns a scalar. It calls the + # acquisition function with one point at a time, so the acquisition function + # returns an array of shape [1, 1], so we index to return a scalar. Note that + # we also return the negative of the acquisition function - this is because + # acquisition functions should be *maximimized* but the Jaxopt minimizer + # minimizes functions. + def scalar_acquisition_fn(x: Float[Array, "1 D"]) -> ScalarFloat: + return -acquisition_function(x)[0][0] + + lbfgsb = ScipyBoundedMinimize(fun=scalar_acquisition_fn, method="l-bfgs-b") + bounds = (search_space.lower_bounds, search_space.upper_bounds) + optimised_point = lbfgsb.run(best_initial_sample_point, bounds=bounds).params + return optimised_point diff --git a/tests/test_decision_making/test_acquisition_maximizer.py b/tests/test_decision_making/test_acquisition_maximizer.py new file mode 100644 index 000000000..f50e7e019 --- /dev/null +++ b/tests/test_decision_making/test_acquisition_maximizer.py @@ -0,0 +1,216 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from abc import ABC + +from jax.config import config +import jax.numpy as jnp +import jax.random as jr +from jaxtyping import ( + Array, + Float, +) +import pytest + +from gpjax.decision_making.acquisition_maximizer import ( + AbstractAcquisitionMaximizer, + ContinuousAcquisitionMaximizer, + _get_discrete_maximizer, +) +from gpjax.decision_making.search_space import ContinuousSearchSpace +from gpjax.typing import KeyArray + +config.update("jax_enable_x64", True) + + +class TestContinuousAcquisitionFunction(ABC): + search_space: ContinuousSearchSpace + maximizer: Float[Array, "1 D"] + + def evaluate(x: Float[Array, "N D"]) -> Float[Array, "N 1"]: + raise NotImplementedError + + +class NegativeForrester(TestContinuousAcquisitionFunction): + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([0.0], dtype=jnp.float64), + upper_bounds=jnp.array([1.0], dtype=jnp.float64), + ) + maximizer = jnp.array([[0.75725]]) + + def evaluate(self, x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: + return -((6 * x - 2) ** 2) * jnp.sin(12 * x - 4) + + +class NegativeGoldsteinPrice(TestContinuousAcquisitionFunction): + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([-2.0, -2.0], dtype=jnp.float64), + upper_bounds=jnp.array([2.0, 2.0], dtype=jnp.float64), + ) + maximizer = jnp.array([[0.0, -1.0]]) + + def evaluate(self, x: Float[Array, "N 2"]) -> Float[Array, "N 1"]: + x1 = x[:, 0] + x2 = x[:, 1] + a = 1.0 + (x1 + x2 + 1.0) ** 2 * ( + 19.0 + - 14.0 * x1 + + 3.0 * (x1**2) + - 14.0 * x2 + + 6.0 * x1 * x2 + + 3.0 * (x2**2) + ) + b = 30.0 + (2.0 * x1 - 3.0 * x2) ** 2 * ( + 18.0 + - 32.0 * x1 + + 12.0 * (x1**2) + + 48.0 * x2 + - 36.0 * x1 * x2 + + 27.0 * (x2**2) + ) + return -(a * b).reshape(-1, 1) + + +class Quadratic(TestContinuousAcquisitionFunction): + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([0.0], dtype=jnp.float64), + upper_bounds=jnp.array([1.0], dtype=jnp.float64), + ) + maximizer = jnp.array([[0.5]]) + + def evaluate(self, x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: + return -((x - 0.5) ** 2) + + +def test_abstract_acquisition_maximizer(): + with pytest.raises(TypeError): + AbstractAcquisitionMaximizer() + + +@pytest.mark.parametrize( + "test_acquisition_function, dimensionality", + [(NegativeForrester(), 1), (NegativeGoldsteinPrice(), 2)], +) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_discrete_maximizer_returns_correct_point( + test_acquisition_function: TestContinuousAcquisitionFunction, + dimensionality: int, + key: KeyArray, +): + query_points = test_acquisition_function.search_space.sample(1000, key=key) + acquisition_vals = test_acquisition_function.evaluate(query_points) + true_max_acquisition_val = jnp.max(acquisition_vals) + discrete_maximizer = _get_discrete_maximizer( + query_points, test_acquisition_function.evaluate + ) + assert discrete_maximizer.shape == (1, dimensionality) + assert discrete_maximizer.dtype == jnp.float64 + assert ( + test_acquisition_function.evaluate(discrete_maximizer)[0][0] + == true_max_acquisition_val + ) + + +@pytest.mark.parametrize("num_initial_samples", [0, -1, -10]) +def test_continuous_maximizer_raises_error_with_erroneous_num_initial_samples( + num_initial_samples: int, +): + with pytest.raises(ValueError): + ContinuousAcquisitionMaximizer(num_initial_samples=num_initial_samples) + + +@pytest.mark.parametrize( + "test_acquisition_function, dimensionality", + [(NegativeForrester(), 1), (NegativeGoldsteinPrice(), 2)], +) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continous_maximizer_returns_same_point_with_same_key( + test_acquisition_function: TestContinuousAcquisitionFunction, + dimensionality: int, + key: KeyArray, +): + continuous_maximizer_one = ContinuousAcquisitionMaximizer(num_initial_samples=2000) + continuous_maximizer_two = ContinuousAcquisitionMaximizer(num_initial_samples=2000) + maximizer_one = continuous_maximizer_one.maximize( + acquisition_function=test_acquisition_function.evaluate, + search_space=test_acquisition_function.search_space, + key=key, + ) + maximizer_two = continuous_maximizer_two.maximize( + acquisition_function=test_acquisition_function.evaluate, + search_space=test_acquisition_function.search_space, + key=key, + ) + assert maximizer_one.shape == (1, dimensionality) + assert maximizer_one.dtype == jnp.float64 + assert maximizer_two.shape == (1, dimensionality) + assert maximizer_two.dtype == jnp.float64 + assert jnp.equal(maximizer_one, maximizer_two).all() + + +@pytest.mark.parametrize( + "test_acquisition_function, dimensionality", + [ + (NegativeForrester(), 1), + (NegativeGoldsteinPrice(), 2), + ], +) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continuous_maximizer_finds_correct_point( + test_acquisition_function: TestContinuousAcquisitionFunction, + dimensionality: int, + key: KeyArray, +): + continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( + num_initial_samples=1000 + ) + maximizer = continuous_acquisition_maximizer.maximize( + acquisition_function=test_acquisition_function.evaluate, + search_space=test_acquisition_function.search_space, + key=key, + ) + assert maximizer.shape == (1, dimensionality) + assert maximizer.dtype == jnp.float64 + assert jnp.allclose(maximizer, test_acquisition_function.maximizer, atol=1e-6).all() + + +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10), jr.PRNGKey(1)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_continuous_maximizer_jaxopt_component(key: KeyArray): + quadratic_acquisition_function = Quadratic() + continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( + num_initial_samples=1 # Force JaxOpt L-GFBS-B to do the heavy lifting + ) + maximizer = continuous_acquisition_maximizer.maximize( + acquisition_function=quadratic_acquisition_function.evaluate, + search_space=quadratic_acquisition_function.search_space, + key=key, + ) + assert maximizer.shape == (1, 1) + assert maximizer.dtype == jnp.float64 + assert jnp.allclose( + maximizer, quadratic_acquisition_function.maximizer, atol=1e-6 + ).all() From 369637d404815fc98a1ed1119dfa86cfa7c3b6e8 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Tue, 15 Aug 2023 14:50:32 +0100 Subject: [PATCH 15/76] Implement CR feedback Main changes are as follows: 1. Improve acquisition function tests by creating some standard test functions (e.g. Forrester function) in their own file, as in Trieste, and using these for all tests. 2. Add `num_restarts` attribute to `ContinuousAcquisitionMaximizer` class, so we can run optimiser several times with different sets of randomly sampled initial points. 3. Improve docstrings. 4. Add relevant citations to `citations.py`. --- gpjax/__init__.py | 6 +- gpjax/citation.py | 43 +++++ gpjax/decision_making/__init__.py | 32 +++- .../acquisition_functions/base.py | 42 ++++- .../thompson_sampling.py | 37 +++- .../decision_making/acquisition_maximizer.py | 70 +++++-- .../test_functions/__init__.py | 28 +++ .../test_functions/continuous_functions.py | 162 ++++++++++++++++ tests/test_citations.py | 62 +++++++ .../test_thompson_sampling.py | 159 ++++++++-------- .../test_acquisition_maximizer.py | 171 +++++++---------- .../test_test_functions/__init__.py | 0 .../test_continuous_functions.py | 174 ++++++++++++++++++ 13 files changed, 765 insertions(+), 221 deletions(-) create mode 100644 gpjax/decision_making/test_functions/__init__.py create mode 100644 gpjax/decision_making/test_functions/continuous_functions.py create mode 100644 tests/test_decision_making/test_test_functions/__init__.py create mode 100644 tests/test_decision_making/test_test_functions/test_continuous_functions.py diff --git a/gpjax/__init__.py b/gpjax/__init__.py index b7c5c061e..02af6cca6 100644 --- a/gpjax/__init__.py +++ b/gpjax/__init__.py @@ -12,7 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from gpjax import integrators +from gpjax import ( + decision_making, + integrators, +) from gpjax.base import ( Module, param_field, @@ -80,6 +83,7 @@ "Module", "param_field", "cite", + "decision_making", "kernels", "fit", "Prior", diff --git a/gpjax/citation.py b/gpjax/citation.py index 74a7a7391..56202d2ab 100644 --- a/gpjax/citation.py +++ b/gpjax/citation.py @@ -10,6 +10,11 @@ from jaxlib.xla_extension import PjitFunction from plum import dispatch +from gpjax.decision_making.acquisition_functions import ThompsonSampling +from gpjax.decision_making.test_functions import ( + Forrester, + LogarithmicGoldsteinPrice, +) from gpjax.kernels import ( RFF, ArcCosine, @@ -194,3 +199,41 @@ def cite(tree: ELBO) -> PaperCitation: booktitle="Uncertainty in Artificial Intelligence", citation_type="article", ) + + +#################### +# Decision making citations +#################### +@dispatch +def cite(tree: ThompsonSampling) -> PaperCitation: + return PaperCitation( + citation_key="wilson2020efficiently", + title="Efficiently sampling functions from Gaussian process posteriors", + authors="Wilson, James and Borovitskiy, Viacheslav and Terenin, Alexander and Mostowsky, Peter and Deisenroth, Marc", + year="2020", + booktitle="International Conference on Machine Learning", + citation_type="article", + ) + + +@dispatch +def cite(tree: Forrester) -> BookCitation: + return BookCitation( + citation_key="forrester2008engineering", + authors="Forrester, Alexander and Sobester, Andras and Keane, Andy", + title="Engineering design via surrogate modelling: a practical guide", + year="2008", + publisher="John Wiley & Sons", + ) + + +@dispatch +def cite(tree: LogarithmicGoldsteinPrice) -> PaperCitation: + return PaperCitation( + citation_key="picheny2013benchmark", + authors="Picheny, Victor and Wagner, Tobias and Ginsbourger, David", + title="A benchmark of kriging-based infill criteria for noisy optimization", + year="2013", + booktitle="Structural and multidisciplinary optimization", + citation_type="article", + ) diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index 97e59c17a..6782f6b2e 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -12,8 +12,36 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from gpjax.decision_making import search_space +from gpjax.decision_making.acquisition_functions import ( + AbstractAcquisitionFunctionBuilder, + AcquisitionFunction, + ThompsonSampling, +) +from gpjax.decision_making.acquisition_maximizer import ( + AbstractAcquisitionMaximizer, + ContinuousAcquisitionMaximizer, +) +from gpjax.decision_making.search_space import ( + AbstractSearchSpace, + ContinuousSearchSpace, +) +from gpjax.decision_making.test_functions import ( + AbstractContinuousTestFunction, + Forrester, + LogarithmicGoldsteinPrice, + Quadratic, +) __all__ = [ - "search_space", + "AbstractAcquisitionFunctionBuilder", + "AbstractAcquisitionMaximizer", + "AbstractSearchSpace", + "AcquisitionFunction", + "ContinuousAcquisitionMaximizer", + "ContinuousSearchSpace", + "AbstractContinuousTestFunction", + "Forrester", + "LogarithmicGoldsteinPrice", + "Quadratic", + "ThompsonSampling", ] diff --git a/gpjax/decision_making/acquisition_functions/base.py b/gpjax/decision_making/acquisition_functions/base.py index 9bd031414..59cfcbf8e 100644 --- a/gpjax/decision_making/acquisition_functions/base.py +++ b/gpjax/decision_making/acquisition_functions/base.py @@ -17,13 +17,14 @@ abstractmethod, ) from dataclasses import dataclass -from typing import ( + +from beartype.typing import ( Callable, Mapping, - Optional, ) from gpjax.dataset import Dataset +from gpjax.decision_making.utils import OBJECTIVE from gpjax.gps import AbstractPosterior from gpjax.typing import ( Array, @@ -44,14 +45,49 @@ class AbstractAcquisitionFunctionBuilder(ABC): Abstract class for building acquisition functions. """ + def check_objective_present( + self, + posteriors: Mapping[str, AbstractPosterior], + datasets: Mapping[str, Dataset], + ) -> None: + """ + Check that the objective posterior and dataset are present in the posteriors and + datasets. + + Args: + posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be + used to form the acquisition function. + datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used + to form the acquisition function. + + Raises: + ValueError: If the objective posterior or dataset are not present in the + posteriors or datasets. + """ + if OBJECTIVE not in posteriors.keys(): + raise ValueError("Objective posterior not found in posteriors") + elif OBJECTIVE not in datasets.keys(): + raise ValueError("Objective dataset not found in datasets") + @abstractmethod def build_acquisition_function( self, posteriors: Mapping[str, AbstractPosterior], - datasets: Optional[Mapping[str, Dataset]], + datasets: Mapping[str, Dataset], key: KeyArray, ) -> AcquisitionFunction: """ Build an `AcquisitionFunction` from a set of posteriors and datasets. + + Args: + posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be + used to form the acquisition function. + datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used + to form the acquisition function. + key (KeyArray): JAX PRNG key used for random number generation. + + Returns: + AcquisitionFunction: Acquisition function to be *maximised* in order to + decide which point to query next. """ raise NotImplementedError diff --git a/gpjax/decision_making/acquisition_functions/thompson_sampling.py b/gpjax/decision_making/acquisition_functions/thompson_sampling.py index c13e64ab3..aef397222 100644 --- a/gpjax/decision_making/acquisition_functions/thompson_sampling.py +++ b/gpjax/decision_making/acquisition_functions/thompson_sampling.py @@ -13,7 +13,8 @@ # limitations under the License. # ============================================================================== from dataclasses import dataclass -from typing import Mapping + +from beartype.typing import Mapping from gpjax.dataset import Dataset from gpjax.decision_making.acquisition_functions.base import ( @@ -29,7 +30,9 @@ class ThompsonSampling(AbstractAcquisitionFunctionBuilder): """ Form an acquisition function by drawing an approximate sample from the posterior, - using decoupled sampling as introduced in [Wilson et. al. (2020)](https://arxiv.org/abs/2002.09309). + using decoupled sampling as introduced in [Wilson et. al. + (2020)](https://arxiv.org/abs/2002.09309). Note that we return the *negative* of the + sample as the acquisition function, as acquisition functions are *maximised*. """ num_rff_features: int = 500 @@ -40,14 +43,28 @@ def build_acquisition_function( datasets: Mapping[str, Dataset], key: KeyArray, ) -> AcquisitionFunction: - if OBJECTIVE not in posteriors.keys(): - raise ValueError("Objective posterior not found in posteriors") - if OBJECTIVE not in datasets.keys(): - raise ValueError("Objective dataset not found in datasets") - if key is None: - raise ValueError( - "Key must be provided to draw an approximate sample from the posterior" - ) + """ + Draw an approximate sample from the posterior of the objective model and return + the *negative* of this sample as an acquisition function, as acquisition functions + are *maximised*. + + Args: + posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be + used to form the acquisition function. One of the posteriors must correspond + to the `OBJECTIVE` key, as we sample from the objective posterior to form + the acquisition function. + datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used + to form the acquisition function. Keys in `datasets` should correspond to + keys in `posteriors`. One of the datasets must correspond + to the `OBJECTIVE` key. + key (KeyArray): JAX PRNG key used for random number generation. + + Returns: + AcquisitionFunction: An appproximate sample from the objective model + posterior to to be *maximised* in order to decide which point to query + next. + """ + self.check_objective_present(posteriors, datasets) objective_posterior = posteriors[OBJECTIVE] if not isinstance(objective_posterior, ConjugatePosterior): diff --git a/gpjax/decision_making/acquisition_maximizer.py b/gpjax/decision_making/acquisition_maximizer.py index 79a446220..1f75f5ced 100644 --- a/gpjax/decision_making/acquisition_maximizer.py +++ b/gpjax/decision_making/acquisition_maximizer.py @@ -19,6 +19,7 @@ from dataclasses import dataclass import jax.numpy as jnp +import jax.random as jr from jaxopt import ScipyBoundedMinimize from gpjax.decision_making.acquisition_functions import AcquisitionFunction @@ -90,16 +91,23 @@ class ContinuousAcquisitionMaximizer(AbstractAcquisitionMaximizer): """The `ContinuousAcquisitionMaximizer` class is used to maximize acquisition functions over the continuous domain with L-BFGS-B. First we sample the acquisition function at `num_initial_samples` points from the search space, and then we run - L-BFGS-B from the best of these initial points. + L-BFGS-B from the best of these initial points. We run this process `num_restarts` + number of times, each time sampling a different random set of + `num_initial_samples`initial points. """ num_initial_samples: int + num_restarts: int def __post_init__(self): if self.num_initial_samples < 1: raise ValueError( f"num_initial_samples must be greater than 0, got {self.num_initial_samples}." ) + elif self.num_restarts < 1: + raise ValueError( + f"num_restarts must be greater than 0, got {self.num_restarts}." + ) def maximize( self, @@ -107,21 +115,45 @@ def maximize( search_space: ContinuousSearchSpace, key: KeyArray, ) -> Float[Array, "1 D"]: - initial_sample_points = search_space.sample(self.num_initial_samples, key=key) - best_initial_sample_point = _get_discrete_maximizer( - initial_sample_points, acquisition_function - ) - - # Jaxopt minimizer requires a function which returns a scalar. It calls the - # acquisition function with one point at a time, so the acquisition function - # returns an array of shape [1, 1], so we index to return a scalar. Note that - # we also return the negative of the acquisition function - this is because - # acquisition functions should be *maximimized* but the Jaxopt minimizer - # minimizes functions. - def scalar_acquisition_fn(x: Float[Array, "1 D"]) -> ScalarFloat: - return -acquisition_function(x)[0][0] - - lbfgsb = ScipyBoundedMinimize(fun=scalar_acquisition_fn, method="l-bfgs-b") - bounds = (search_space.lower_bounds, search_space.upper_bounds) - optimised_point = lbfgsb.run(best_initial_sample_point, bounds=bounds).params - return optimised_point + max_observed_acquisition_function_value = None + maximizer = None + + for _ in range(self.num_restarts): + key, _ = jr.split(key) + initial_sample_points = search_space.sample( + self.num_initial_samples, key=key + ) + best_initial_sample_point = _get_discrete_maximizer( + initial_sample_points, acquisition_function + ) + + def _scalar_acquisition_function(x: Float[Array, "1 D"]) -> ScalarFloat: + """ + The Jaxopt minimizer requires a function which returns a scalar. It calls the + acquisition function with one point at a time, so the acquisition function + returns an array of shape [1, 1], so we index to return a scalar. Note that + we also return the negative of the acquisition function - this is because + acquisition functions should be *maximimized* but the Jaxopt minimizer + minimizes functions. + """ + return -acquisition_function(x)[0][0] + + lbfgsb = ScipyBoundedMinimize( + fun=_scalar_acquisition_function, method="l-bfgs-b" + ) + bounds = (search_space.lower_bounds, search_space.upper_bounds) + optimized_point = lbfgsb.run( + best_initial_sample_point, bounds=bounds + ).params + optimized_acquisition_function_value = _scalar_acquisition_function( + optimized_point + ) + if (max_observed_acquisition_function_value is None) or ( + optimized_acquisition_function_value + > max_observed_acquisition_function_value + ): + max_observed_acquisition_function_value = ( + optimized_acquisition_function_value + ) + maximizer = optimized_point + return maximizer diff --git a/gpjax/decision_making/test_functions/__init__.py b/gpjax/decision_making/test_functions/__init__.py new file mode 100644 index 000000000..8fe075e1b --- /dev/null +++ b/gpjax/decision_making/test_functions/__init__.py @@ -0,0 +1,28 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from gpjax.decision_making.test_functions.continuous_functions import ( + AbstractContinuousTestFunction, + Forrester, + LogarithmicGoldsteinPrice, + Quadratic, +) + +__all__ = [ + "AbstractContinuousTestFunction", + "Forrester", + "LogarithmicGoldsteinPrice", + "Quadratic", +] diff --git a/gpjax/decision_making/test_functions/continuous_functions.py b/gpjax/decision_making/test_functions/continuous_functions.py new file mode 100644 index 000000000..7d3f5c4cb --- /dev/null +++ b/gpjax/decision_making/test_functions/continuous_functions.py @@ -0,0 +1,162 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import dataclass + +import jax.numpy as jnp +from jaxtyping import ( + Array, + Float, +) + +from gpjax.dataset import Dataset +from gpjax.decision_making.search_space import ContinuousSearchSpace +from gpjax.typing import KeyArray + + +class AbstractContinuousTestFunction(ABC): + """ + Abstract base class for continuous test functions. + + Attributes: + search_space (ContinuousSearchSpace): Search space for the function. + minimizer (Float[Array, '1 D']): Minimizer of the function (to 5 decimal places) + minimum (Float[Array, '1 1']): Minimum of the function (to 5 decimal places). + """ + + search_space: ContinuousSearchSpace + minimizer: Float[Array, "1 D"] + minimum: Float[Array, "1 1"] + + def generate_dataset(self, num_points: int, key: KeyArray) -> Dataset: + """ + Generate a toy dataset from the test function. + + Args: + num_points (int): Number of points to sample. + key (KeyArray): JAX PRNG key. + + Returns: + Dataset: Dataset of points sampled from the test function. + """ + X = self.search_space.sample(num_points=num_points, key=key) + y = self.evaluate(X) + return Dataset(X=X, y=y) + + def generate_test_points( + self, num_points: int, key: KeyArray + ) -> Float[Array, "N D"]: + """ + Generate test points from the search space of the test function. + + Args: + num_points (int): Number of points to sample. + key (KeyArray): JAX PRNG key. + + Returns: + Float[Array, 'N D']: Test points sampled from the search space. + """ + return self.search_space.sample(num_points=num_points, key=key) + + @abstractmethod + def evaluate(self, x: Float[Array, "N D"]) -> Float[Array, "N 1"]: + """ + Evaluate the test function at a set of points. + + Args: + x (Float[Array, 'N D']): Points to evaluate the test function at. + + Returns: + Float[Array, 'N 1']: Values of the test function at the points. + """ + raise NotImplementedError + + +@dataclass +class Forrester(AbstractContinuousTestFunction): + """ + Forrester function introduced in 'Engineering design via surrogate modelling: a + practical guide' (Forrester et al. 2008), rescaled to have zero mean and unit + variance over $`[0, 1]`$. + """ + + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([0.0]), + upper_bounds=jnp.array([1.0]), + ) + minimizer = jnp.array([[0.75725]]) + minimum = jnp.array([[-1.45280]]) + + def evaluate(self, x: Float[Array, "N D"]) -> Float[Array, "N 1"]: + mean = 0.45321 + std = jnp.sqrt(19.8577) + return (((6 * x - 2) ** 2) * jnp.sin(12 * x - 4) - mean) / std + + +@dataclass +class LogarithmicGoldsteinPrice(AbstractContinuousTestFunction): + """ + Logarithmic Goldstein-Price function introduced in 'A benchmark of kriging-based + infill criteria for noisy optimization' (Picheny et al. 2013), which has zero mean + and unit variance over $`[0, 1]^2`$. + """ + + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([0.0, 0.0]), + upper_bounds=jnp.array([1.0, 1.0]), + ) + minimizer = jnp.array([[0.5, 0.25]]) + minimum = jnp.array([[-3.12913]]) + + def evaluate(self, x: Float[Array, "N D"]) -> Float[Array, "N 1"]: + x1 = 4.0 * x[:, 0] - 2.0 + x2 = 4.0 * x[:, 1] - 2.0 + a = 1.0 + (x1 + x2 + 1.0) ** 2 * ( + 19.0 + - 14.0 * x1 + + 3.0 * (x1**2) + - 14.0 * x2 + + 6.0 * x1 * x2 + + 3.0 * (x2**2) + ) + b = 30.0 + (2.0 * x1 - 3.0 * x2) ** 2 * ( + 18.0 + - 32.0 * x1 + + 12.0 * (x1**2) + + 48.0 * x2 + - 36.0 * x1 * x2 + + 27.0 * (x2**2) + ) + return ((jnp.log((a * b)) - 8.693) / 2.427).reshape(-1, 1) + + +@dataclass +class Quadratic(AbstractContinuousTestFunction): + """ + Toy quadratic function defined over $`[0, 1]`$. + """ + + search_space = ContinuousSearchSpace( + lower_bounds=jnp.array([0.0]), + upper_bounds=jnp.array([1.0]), + ) + minimizer = jnp.array([[0.5]]) + minimum = jnp.array([[0.0]]) + + def evaluate(self, x: Float[Array, "N D"]) -> Float[Array, "N 1"]: + return (x - 0.5) ** 2 diff --git a/tests/test_citations.py b/tests/test_citations.py index df3262f63..a5490da05 100644 --- a/tests/test_citations.py +++ b/tests/test_citations.py @@ -16,6 +16,11 @@ PhDThesisCitation, cite, ) +from gpjax.decision_making import ( + Forrester, + LogarithmicGoldsteinPrice, + ThompsonSampling, +) from gpjax.kernels import ( RBF, RFF, @@ -142,6 +147,63 @@ def test_collapsed_elbo(): _check_no_fallback(citation) +def test_thompson_sampling(): + thompson_sampling = ThompsonSampling() + citation = cite(thompson_sampling) + + assert isinstance(citation, PaperCitation) + assert citation.citation_key == "wilson2020efficiently" + assert ( + citation.title + == "Efficiently sampling functions from Gaussian process posteriors" + ) + assert ( + citation.authors + == "Wilson, James and Borovitskiy, Viacheslav and Terenin, Alexander and Mostowsky, Peter and Deisenroth, Marc" + ) + assert citation.year == "2020" + assert citation.booktitle == "International Conference on Machine Learning" + assert citation.citation_type == "article" + _check_no_fallback(citation) + + +def test_forrester(): + forrester = Forrester() + citation = cite(forrester) + + assert isinstance(citation, BookCitation) + assert citation.citation_key == "forrester2008engineering" + assert ( + citation.title + == "Engineering design via surrogate modelling: a practical guide" + ) + assert ( + citation.authors == "Forrester, Alexander and Sobester, Andras and Keane, Andy" + ) + assert citation.year == "2008" + assert citation.publisher == "John Wiley & Sons" + _check_no_fallback(citation) + + +def test_logarithmic_goldstein_price(): + logarithmic_goldstein_price = LogarithmicGoldsteinPrice() + citation = cite(logarithmic_goldstein_price) + + assert isinstance(citation, PaperCitation) + assert citation.citation_key == "picheny2013benchmark" + assert ( + citation.title + == "A benchmark of kriging-based infill criteria for noisy optimization" + ) + assert ( + citation.authors == "Picheny, Victor and Wagner, Tobias and Ginsbourger, David" + ) + assert citation.year == "2013" + assert citation.booktitle == "Structural and multidisciplinary optimization" + assert citation.citation_type == "article" + _check_no_fallback(citation) + + @pytest.mark.parametrize( "objective", [gpx.ELBO(), gpx.CollapsedELBO(), gpx.LogPosteriorDensity(), gpx.ConjugateMLL()], diff --git a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py index d69480ed3..42943d41c 100644 --- a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py +++ b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py @@ -12,20 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from beartype.typing import Callable from jax.config import config + +config.update("jax_enable_x64", True) + +from beartype.typing import Callable import jax.numpy as jnp import jax.random as jr -from jaxtyping import ( - Array, - Float, -) import pytest from gpjax.dataset import Dataset from gpjax.decision_making.acquisition_functions.thompson_sampling import ( ThompsonSampling, ) +from gpjax.decision_making.test_functions.continuous_functions import ( + AbstractContinuousTestFunction, + Forrester, + LogarithmicGoldsteinPrice, +) from gpjax.decision_making.utils import OBJECTIVE from gpjax.gps import ( ConjugatePosterior, @@ -38,43 +42,7 @@ Poisson, ) from gpjax.mean_functions import Zero - -config.update("jax_enable_x64", True) - - -def generate_dummy_1d_dataset() -> Dataset: - X = jr.uniform(key=jr.PRNGKey(42), minval=0.0, maxval=10.0, shape=(10, 1)) - y = jnp.sin(X) + X + 1.0 + 10 * jr.normal(jr.PRNGKey(42), shape=X.shape) - D = Dataset(X, y) - return D - - -def generate_dummy_2d_dataset() -> Dataset: - X = jr.uniform(key=jr.PRNGKey(42), minval=0.0, maxval=10.0, shape=(10, 2)) - X0 = X[:, 0].reshape(-1, 1) - X1 = X[:, 1].reshape(-1, 1) - y = ( - jnp.sin(X0) - + X1 - + X0**2 - + 1.0 - + 10 * jr.normal(jr.PRNGKey(42), shape=X0.shape) - ) - D = Dataset(X, y) - return D - - -def generate_dummy_1d_test_X(num_test_points: int) -> Float[Array, "N 1"]: - test_X = jnp.linspace(0.0, 10.0, num_test_points).reshape(-1, 1) - return test_X - - -def generate_dummy_2d_test_X(sqrt_num_test_points: int) -> Float[Array, "N 2"]: - test_X0 = jnp.linspace(0.0, 10.0, sqrt_num_test_points) - test_X1 = jnp.linspace(0.0, 10.0, sqrt_num_test_points) - test_X0, test_X1 = jnp.meshgrid(test_X0, test_X1) - test_X = jnp.column_stack((test_X0.ravel(), test_X1.ravel())) - return test_X +from gpjax.typing import KeyArray def generate_dummy_conjugate_posterior(dataset: Dataset) -> ConjugatePosterior: @@ -95,12 +63,16 @@ def generate_dummy_non_conjugate_posterior(dataset: Dataset) -> NonConjugatePost return posterior +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_thompson_sampling_no_objective_posterior_raises_error(): - dataset = generate_dummy_1d_dataset() + key = jr.PRNGKey(42) + forrester = Forrester() + dataset = forrester.generate_dataset(num_points=10, key=key) posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {"CONSTRAINT": posterior} datasets = {OBJECTIVE: dataset} - key = jr.PRNGKey(42) with pytest.raises(ValueError): ts_acquisition_builder = ThompsonSampling(num_rff_features=500) ts_acquisition_builder.build_acquisition_function( @@ -108,12 +80,16 @@ def test_thompson_sampling_no_objective_posterior_raises_error(): ) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_thompson_sampling_no_objective_dataset_raises_error(): - dataset = generate_dummy_1d_dataset() + key = jr.PRNGKey(42) + forrester = Forrester() + dataset = forrester.generate_dataset(num_points=10, key=key) posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {"CONSTRAINT": dataset} - key = jr.PRNGKey(42) with pytest.raises(ValueError): ts_acquisition_builder = ThompsonSampling(num_rff_features=500) ts_acquisition_builder.build_acquisition_function( @@ -121,24 +97,16 @@ def test_thompson_sampling_no_objective_dataset_raises_error(): ) -def test_thompson_sampling_none_key_raises_error(): - dataset = generate_dummy_1d_dataset() - posterior = generate_dummy_conjugate_posterior(dataset) - posteriors = {OBJECTIVE: posterior} - datasets = {OBJECTIVE: dataset} - with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) - ts_acquisition_builder.build_acquisition_function( - posteriors=posteriors, datasets=datasets, key=None - ) - - +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_thompson_sampling_non_conjugate_posterior_raises_error(): - dataset = generate_dummy_1d_dataset() + key = jr.PRNGKey(42) + forrester = Forrester() + dataset = forrester.generate_dataset(num_points=10, key=key) posterior = generate_dummy_non_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - key = jr.PRNGKey(42) with pytest.raises(ValueError): ts_acquisition_builder = ThompsonSampling(num_rff_features=500) ts_acquisition_builder.build_acquisition_function( @@ -147,35 +115,51 @@ def test_thompson_sampling_non_conjugate_posterior_raises_error(): @pytest.mark.parametrize( - "dataset, dimensionality", - [(generate_dummy_1d_dataset(), 1), (generate_dummy_2d_dataset(), 2)], + "test_target_function", + [(Forrester()), (LogarithmicGoldsteinPrice())], ) -@pytest.mark.parametrize("num_test_points", [49, 100]) +@pytest.mark.parametrize("num_test_points", [50, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_thompson_sampling_acquisition_function_correct_shapes( - dataset: Dataset, dimensionality: int, num_test_points: int + test_target_function: AbstractContinuousTestFunction, + num_test_points: int, + key: KeyArray, ): + dataset = test_target_function.generate_dataset(num_points=10, key=key) posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - key = jr.PRNGKey(42) ts_acquisition_builder = ThompsonSampling(num_rff_features=500) ts_acquisition_function = ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) - if dimensionality == 1: - test_X = generate_dummy_1d_test_X(num_test_points) - elif dimensionality == 2: - test_X = generate_dummy_2d_test_X(int(jnp.sqrt(num_test_points))) + test_key, _ = jr.split(key) + test_X = test_target_function.generate_test_points(num_test_points, test_key) ts_acquisition_function_values = ts_acquisition_function(test_X) assert ts_acquisition_function_values.shape == (num_test_points, 1) -def test_thompson_sampling_acquisition_function_same_key_same_function(): - dataset = generate_dummy_1d_dataset() +@pytest.mark.parametrize( + "test_target_function", + [(Forrester()), (LogarithmicGoldsteinPrice())], +) +@pytest.mark.parametrize("num_test_points", [50, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_thompson_sampling_acquisition_function_same_key_same_function( + test_target_function: AbstractContinuousTestFunction, + num_test_points: int, + key: KeyArray, +): + dataset = test_target_function.generate_dataset(num_points=10, key=key) posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - key = jr.PRNGKey(42) ts_acquisition_builder_one = ThompsonSampling(num_rff_features=500) ts_acquisition_builder_two = ThompsonSampling(num_rff_features=500) ts_acquisition_function_one = ts_acquisition_builder_one.build_acquisition_function( @@ -184,7 +168,8 @@ def test_thompson_sampling_acquisition_function_same_key_same_function(): ts_acquisition_function_two = ts_acquisition_builder_two.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) - test_X = jnp.linspace(0.0, 10.0, 100).reshape(-1, 1) + test_key, _ = jr.split(key) + test_X = test_target_function.generate_test_points(num_test_points, test_key) ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) assert isinstance(ts_acquisition_function_one, Callable) @@ -194,21 +179,35 @@ def test_thompson_sampling_acquisition_function_same_key_same_function(): ).all() -def test_thompson_sampling_acquisition_function_different_key_different_function(): - dataset = generate_dummy_1d_dataset() +@pytest.mark.parametrize( + "test_target_function", + [(Forrester()), (LogarithmicGoldsteinPrice())], +) +@pytest.mark.parametrize("num_test_points", [50, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_thompson_sampling_acquisition_function_different_key_different_function( + test_target_function: AbstractContinuousTestFunction, + num_test_points: int, + key: KeyArray, +): + dataset = test_target_function.generate_dataset(num_points=10, key=key) posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - key_one = jr.PRNGKey(42) - key_two = jr.PRNGKey(43) + sample_one_key = key + sample_two_key, _ = jr.split(key) ts_acquisition_builder = ThompsonSampling(num_rff_features=500) ts_acquisition_function_one = ts_acquisition_builder.build_acquisition_function( - posteriors=posteriors, datasets=datasets, key=key_one + posteriors=posteriors, datasets=datasets, key=sample_one_key ) ts_acquisition_function_two = ts_acquisition_builder.build_acquisition_function( - posteriors=posteriors, datasets=datasets, key=key_two + posteriors=posteriors, datasets=datasets, key=sample_two_key ) - test_X = jnp.linspace(0.0, 10.0, 100).reshape(-1, 1) + test_key, _ = jr.split(sample_two_key) + test_X = test_target_function.generate_test_points(num_test_points, test_key) ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) assert isinstance(ts_acquisition_function_one, Callable) diff --git a/tests/test_decision_making/test_acquisition_maximizer.py b/tests/test_decision_making/test_acquisition_maximizer.py index f50e7e019..34dfc1fa5 100644 --- a/tests/test_decision_making/test_acquisition_maximizer.py +++ b/tests/test_decision_making/test_acquisition_maximizer.py @@ -12,16 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== +from jax.config import config -from abc import ABC +config.update("jax_enable_x64", True) -from jax.config import config import jax.numpy as jnp import jax.random as jr -from jaxtyping import ( - Array, - Float, -) import pytest from gpjax.decision_making.acquisition_maximizer import ( @@ -29,70 +25,14 @@ ContinuousAcquisitionMaximizer, _get_discrete_maximizer, ) -from gpjax.decision_making.search_space import ContinuousSearchSpace +from gpjax.decision_making.test_functions.continuous_functions import ( + AbstractContinuousTestFunction, + Forrester, + LogarithmicGoldsteinPrice, + Quadratic, +) from gpjax.typing import KeyArray -config.update("jax_enable_x64", True) - - -class TestContinuousAcquisitionFunction(ABC): - search_space: ContinuousSearchSpace - maximizer: Float[Array, "1 D"] - - def evaluate(x: Float[Array, "N D"]) -> Float[Array, "N 1"]: - raise NotImplementedError - - -class NegativeForrester(TestContinuousAcquisitionFunction): - search_space = ContinuousSearchSpace( - lower_bounds=jnp.array([0.0], dtype=jnp.float64), - upper_bounds=jnp.array([1.0], dtype=jnp.float64), - ) - maximizer = jnp.array([[0.75725]]) - - def evaluate(self, x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: - return -((6 * x - 2) ** 2) * jnp.sin(12 * x - 4) - - -class NegativeGoldsteinPrice(TestContinuousAcquisitionFunction): - search_space = ContinuousSearchSpace( - lower_bounds=jnp.array([-2.0, -2.0], dtype=jnp.float64), - upper_bounds=jnp.array([2.0, 2.0], dtype=jnp.float64), - ) - maximizer = jnp.array([[0.0, -1.0]]) - - def evaluate(self, x: Float[Array, "N 2"]) -> Float[Array, "N 1"]: - x1 = x[:, 0] - x2 = x[:, 1] - a = 1.0 + (x1 + x2 + 1.0) ** 2 * ( - 19.0 - - 14.0 * x1 - + 3.0 * (x1**2) - - 14.0 * x2 - + 6.0 * x1 * x2 - + 3.0 * (x2**2) - ) - b = 30.0 + (2.0 * x1 - 3.0 * x2) ** 2 * ( - 18.0 - - 32.0 * x1 - + 12.0 * (x1**2) - + 48.0 * x2 - - 36.0 * x1 * x2 - + 27.0 * (x2**2) - ) - return -(a * b).reshape(-1, 1) - - -class Quadratic(TestContinuousAcquisitionFunction): - search_space = ContinuousSearchSpace( - lower_bounds=jnp.array([0.0], dtype=jnp.float64), - upper_bounds=jnp.array([1.0], dtype=jnp.float64), - ) - maximizer = jnp.array([[0.5]]) - - def evaluate(self, x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: - return -((x - 0.5) ** 2) - def test_abstract_acquisition_maximizer(): with pytest.raises(TypeError): @@ -100,30 +40,26 @@ def test_abstract_acquisition_maximizer(): @pytest.mark.parametrize( - "test_acquisition_function, dimensionality", - [(NegativeForrester(), 1), (NegativeGoldsteinPrice(), 2)], + "test_function, dimensionality", + [(Forrester(), 1), (LogarithmicGoldsteinPrice(), 2)], ) @pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_discrete_maximizer_returns_correct_point( - test_acquisition_function: TestContinuousAcquisitionFunction, + test_function: AbstractContinuousTestFunction, dimensionality: int, key: KeyArray, ): - query_points = test_acquisition_function.search_space.sample(1000, key=key) - acquisition_vals = test_acquisition_function.evaluate(query_points) + query_points = test_function.search_space.sample(1000, key=key) + acquisition_function = lambda x: -1.0 * test_function.evaluate(x) + acquisition_vals = acquisition_function(query_points) true_max_acquisition_val = jnp.max(acquisition_vals) - discrete_maximizer = _get_discrete_maximizer( - query_points, test_acquisition_function.evaluate - ) + discrete_maximizer = _get_discrete_maximizer(query_points, acquisition_function) assert discrete_maximizer.shape == (1, dimensionality) assert discrete_maximizer.dtype == jnp.float64 - assert ( - test_acquisition_function.evaluate(discrete_maximizer)[0][0] - == true_max_acquisition_val - ) + assert acquisition_function(discrete_maximizer)[0][0] == true_max_acquisition_val @pytest.mark.parametrize("num_initial_samples", [0, -1, -10]) @@ -131,32 +67,49 @@ def test_continuous_maximizer_raises_error_with_erroneous_num_initial_samples( num_initial_samples: int, ): with pytest.raises(ValueError): - ContinuousAcquisitionMaximizer(num_initial_samples=num_initial_samples) + ContinuousAcquisitionMaximizer( + num_initial_samples=num_initial_samples, num_restarts=1 + ) + + +@pytest.mark.parametrize("num_restarts", [0, -1, -10]) +def test_continuous_maximizer_raises_error_with_erroneous_num_restarts( + num_restarts: int, +): + with pytest.raises(ValueError): + ContinuousAcquisitionMaximizer(num_initial_samples=1, num_restarts=num_restarts) @pytest.mark.parametrize( - "test_acquisition_function, dimensionality", - [(NegativeForrester(), 1), (NegativeGoldsteinPrice(), 2)], + "test_function, dimensionality", + [(Forrester(), 1), (LogarithmicGoldsteinPrice(), 2)], ) @pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.parametrize("num_restarts", [1, 3]) @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_continous_maximizer_returns_same_point_with_same_key( - test_acquisition_function: TestContinuousAcquisitionFunction, + test_function: AbstractContinuousTestFunction, dimensionality: int, key: KeyArray, + num_restarts: int, ): - continuous_maximizer_one = ContinuousAcquisitionMaximizer(num_initial_samples=2000) - continuous_maximizer_two = ContinuousAcquisitionMaximizer(num_initial_samples=2000) + continuous_maximizer_one = ContinuousAcquisitionMaximizer( + num_initial_samples=1000, num_restarts=num_restarts + ) + continuous_maximizer_two = ContinuousAcquisitionMaximizer( + num_initial_samples=1000, num_restarts=num_restarts + ) + acquisition_function = lambda x: -1.0 * test_function.evaluate(x) maximizer_one = continuous_maximizer_one.maximize( - acquisition_function=test_acquisition_function.evaluate, - search_space=test_acquisition_function.search_space, + acquisition_function=acquisition_function, + search_space=test_function.search_space, key=key, ) maximizer_two = continuous_maximizer_two.maximize( - acquisition_function=test_acquisition_function.evaluate, - search_space=test_acquisition_function.search_space, + acquisition_function=acquisition_function, + search_space=test_function.search_space, key=key, ) assert maximizer_one.shape == (1, dimensionality) @@ -167,50 +120,56 @@ def test_continous_maximizer_returns_same_point_with_same_key( @pytest.mark.parametrize( - "test_acquisition_function, dimensionality", + "test_function, dimensionality", [ - (NegativeForrester(), 1), - (NegativeGoldsteinPrice(), 2), + (Forrester(), 1), + (LogarithmicGoldsteinPrice(), 2), ], ) @pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.parametrize("num_restarts", [1, 3]) @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_continuous_maximizer_finds_correct_point( - test_acquisition_function: TestContinuousAcquisitionFunction, + test_function: AbstractContinuousTestFunction, dimensionality: int, key: KeyArray, + num_restarts: int, ): continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( - num_initial_samples=1000 + num_initial_samples=1000, num_restarts=num_restarts ) + acquisition_function = lambda x: -1.0 * test_function.evaluate(x) + true_acquisition_maximizer = test_function.minimizer maximizer = continuous_acquisition_maximizer.maximize( - acquisition_function=test_acquisition_function.evaluate, - search_space=test_acquisition_function.search_space, + acquisition_function=acquisition_function, + search_space=test_function.search_space, key=key, ) assert maximizer.shape == (1, dimensionality) assert maximizer.dtype == jnp.float64 - assert jnp.allclose(maximizer, test_acquisition_function.maximizer, atol=1e-6).all() + assert jnp.allclose(maximizer, true_acquisition_maximizer, atol=1e-6).all() @pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10), jr.PRNGKey(1)]) +@pytest.mark.parametrize("num_restarts", [1, 3]) @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_continuous_maximizer_jaxopt_component(key: KeyArray): - quadratic_acquisition_function = Quadratic() +def test_continuous_maximizer_jaxopt_component(key: KeyArray, num_restarts: int): + quadratic = Quadratic() continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( - num_initial_samples=1 # Force JaxOpt L-GFBS-B to do the heavy lifting + num_initial_samples=1, # Force JaxOpt L-GFBS-B to do the heavy lifting + num_restarts=num_restarts, ) + acquisition_function = lambda x: -1.0 * quadratic.evaluate(x) + true_acquisition_maximizer = quadratic.minimizer maximizer = continuous_acquisition_maximizer.maximize( - acquisition_function=quadratic_acquisition_function.evaluate, - search_space=quadratic_acquisition_function.search_space, + acquisition_function=acquisition_function, + search_space=quadratic.search_space, key=key, ) assert maximizer.shape == (1, 1) assert maximizer.dtype == jnp.float64 - assert jnp.allclose( - maximizer, quadratic_acquisition_function.maximizer, atol=1e-6 - ).all() + assert jnp.allclose(maximizer, true_acquisition_maximizer, atol=1e-6).all() diff --git a/tests/test_decision_making/test_test_functions/__init__.py b/tests/test_decision_making/test_test_functions/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_decision_making/test_test_functions/test_continuous_functions.py b/tests/test_decision_making/test_test_functions/test_continuous_functions.py new file mode 100644 index 000000000..5e13c8ce5 --- /dev/null +++ b/tests/test_decision_making/test_test_functions/test_continuous_functions.py @@ -0,0 +1,174 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax.config import config +import jax.numpy as jnp +import jax.random as jr +import pytest + +from gpjax.decision_making.test_functions import ( + AbstractContinuousTestFunction, + Forrester, + LogarithmicGoldsteinPrice, + Quadratic, +) +from gpjax.typing import KeyArray + +config.update("jax_enable_x64", True) + + +def test_abstract_continuous_test_function(): + with pytest.raises(TypeError): + AbstractContinuousTestFunction() + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +def test_minimizer_evaluates_to_minimum(test_function: AbstractContinuousTestFunction): + assert jnp.allclose( + test_function.evaluate(test_function.minimizer), + test_function.minimum, + atol=1e-5, + ).all() + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_correct_minimum(test_function: AbstractContinuousTestFunction, key: KeyArray): + test_x = test_function.generate_test_points(100000, key) + function_vals = test_function.evaluate(test_x) + vals_minus_minimum = function_vals - test_function.minimum + assert jnp.all(vals_minus_minimum >= -1e-5) + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_consistent_dtype(test_function: AbstractContinuousTestFunction): + minimizer = test_function.minimizer + minimum = test_function.minimum + dataset = test_function.generate_dataset(10, jr.PRNGKey(42)) + test_x = test_function.generate_test_points(10, jr.PRNGKey(42)) + assert minimizer.dtype == minimum.dtype + assert minimizer.dtype == dataset.X.dtype + assert minimizer.dtype == dataset.y.dtype + assert minimizer.dtype == test_x.dtype + + +@pytest.mark.parametrize( + "test_function, dimensionality", + [(Quadratic(), 1), (Forrester(), 1), (LogarithmicGoldsteinPrice(), 2)], +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_test_points_shape( + test_function: AbstractContinuousTestFunction, dimensionality: int, num_samples: int +): + test_X = test_function.generate_test_points(num_samples, jr.PRNGKey(42)) + assert test_X.shape == (num_samples, dimensionality) + + +@pytest.mark.parametrize( + "test_function, dimensionality", + [(Quadratic(), 1), (Forrester(), 1), (LogarithmicGoldsteinPrice(), 2)], +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_dataset_shapes( + test_function: AbstractContinuousTestFunction, dimensionality: int, num_samples: int +): + dataset = test_function.generate_dataset(num_samples, jr.PRNGKey(42)) + assert dataset.X.shape == (num_samples, dimensionality) + assert dataset.y.shape == (num_samples, 1) + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_same_key_same_dataset( + test_function: AbstractContinuousTestFunction, num_samples: int, key: KeyArray +): + dataset_one = test_function.generate_dataset(num_samples, key) + dataset_two = test_function.generate_dataset(num_samples, key) + assert jnp.equal(dataset_one.X, dataset_two.X).all() + assert jnp.equal(dataset_one.y, dataset_two.y).all() + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_different_key_different_dataset( + test_function: AbstractContinuousTestFunction, num_samples: int, key: KeyArray +): + dataset_one = test_function.generate_dataset(num_samples, key) + key, _ = jr.split(key) + dataset_two = test_function.generate_dataset(num_samples, key) + assert not jnp.equal(dataset_one.X, dataset_two.X).all() + assert not jnp.equal(dataset_one.y, dataset_two.y).all() + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_same_key_same_test_points( + test_function: AbstractContinuousTestFunction, num_samples: int, key: KeyArray +): + test_points_one = test_function.generate_test_points(num_samples, key) + test_points_two = test_function.generate_test_points(num_samples, key) + assert jnp.equal(test_points_one, test_points_two).all() + + +@pytest.mark.parametrize( + "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_different_key_different_test_points( + test_function: AbstractContinuousTestFunction, num_samples: int, key: KeyArray +): + test_points_one = test_function.generate_test_points(num_samples, key) + key, _ = jr.split(key) + test_points_two = test_function.generate_test_points(num_samples, key) + assert not jnp.equal(test_points_one, test_points_two).all() From 7f74b83d48edc6dec6e78e56d9358feea5c49d18 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Wed, 16 Aug 2023 10:58:55 +0100 Subject: [PATCH 16/76] Fix tests and reduce default num random fourier features for Thompson sampling Set jax config to use 64bit precision in `conftest.py` --- .../thompson_sampling.py | 14 ++++++-- tests/conftest.py | 3 ++ .../test_thompson_sampling.py | 32 +++++++++++++++---- .../test_acquisition_maximizer.py | 2 +- .../test_decision_making/test_search_space.py | 6 ++-- .../test_continuous_functions.py | 21 +++++++----- 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/gpjax/decision_making/acquisition_functions/thompson_sampling.py b/gpjax/decision_making/acquisition_functions/thompson_sampling.py index aef397222..129cb4e97 100644 --- a/gpjax/decision_making/acquisition_functions/thompson_sampling.py +++ b/gpjax/decision_making/acquisition_functions/thompson_sampling.py @@ -33,9 +33,19 @@ class ThompsonSampling(AbstractAcquisitionFunctionBuilder): using decoupled sampling as introduced in [Wilson et. al. (2020)](https://arxiv.org/abs/2002.09309). Note that we return the *negative* of the sample as the acquisition function, as acquisition functions are *maximised*. + + Attributes: + num_features (int): The number of random Fourier features to use when drawing + the approximate sample from the posterior. Defaults to 100. """ - num_rff_features: int = 500 + num_features: int = 100 + + def __post_init__(self): + if self.num_features <= 0: + raise ValueError( + "The number of random Fourier features must be a positive integer." + ) def build_acquisition_function( self, @@ -77,7 +87,7 @@ def build_acquisition_function( num_samples=1, train_data=objective_dataset, key=key, - num_features=self.num_rff_features, + num_features=self.num_features, ) return lambda x: -1.0 * thompson_sample( diff --git a/tests/conftest.py b/tests/conftest.py index e12a1f72d..5ad27d576 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,8 @@ +from jax.config import config from jaxtyping import install_import_hook +config.update("jax_enable_x64", True) + # import gpjax within import hook to apply beartype everywhere, before running tests with install_import_hook("gpjax", "beartype.beartype"): import gpjax # noqa: F401 diff --git a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py index 42943d41c..0d1980fe5 100644 --- a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py +++ b/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py @@ -74,7 +74,7 @@ def test_thompson_sampling_no_objective_posterior_raises_error(): posteriors = {"CONSTRAINT": posterior} datasets = {OBJECTIVE: dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder = ThompsonSampling(num_features=100) ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -91,7 +91,7 @@ def test_thompson_sampling_no_objective_dataset_raises_error(): posteriors = {OBJECTIVE: posterior} datasets = {"CONSTRAINT": dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder = ThompsonSampling(num_features=100) ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -108,7 +108,25 @@ def test_thompson_sampling_non_conjugate_posterior_raises_error(): posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder = ThompsonSampling(num_features=100) + ts_acquisition_builder.build_acquisition_function( + posteriors=posteriors, datasets=datasets, key=key + ) + + +@pytest.mark.parametrize("num_rff_features", [0, -1, -10]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_thompson_sampling_invalid_rff_num_raises_error(num_rff_features: int): + key = jr.PRNGKey(42) + forrester = Forrester() + dataset = forrester.generate_dataset(num_points=10, key=key) + posterior = generate_dummy_conjugate_posterior(dataset) + posteriors = {OBJECTIVE: posterior} + datasets = {OBJECTIVE: dataset} + with pytest.raises(ValueError): + ts_acquisition_builder = ThompsonSampling(num_features=num_rff_features) ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -132,7 +150,7 @@ def test_thompson_sampling_acquisition_function_correct_shapes( posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder = ThompsonSampling(num_features=100) ts_acquisition_function = ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -160,8 +178,8 @@ def test_thompson_sampling_acquisition_function_same_key_same_function( posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - ts_acquisition_builder_one = ThompsonSampling(num_rff_features=500) - ts_acquisition_builder_two = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder_one = ThompsonSampling(num_features=100) + ts_acquisition_builder_two = ThompsonSampling(num_features=100) ts_acquisition_function_one = ts_acquisition_builder_one.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -199,7 +217,7 @@ def test_thompson_sampling_acquisition_function_different_key_different_function datasets = {OBJECTIVE: dataset} sample_one_key = key sample_two_key, _ = jr.split(key) - ts_acquisition_builder = ThompsonSampling(num_rff_features=500) + ts_acquisition_builder = ThompsonSampling(num_features=100) ts_acquisition_function_one = ts_acquisition_builder.build_acquisition_function( posteriors=posteriors, datasets=datasets, key=sample_one_key ) diff --git a/tests/test_decision_making/test_acquisition_maximizer.py b/tests/test_decision_making/test_acquisition_maximizer.py index 34dfc1fa5..939a6f80e 100644 --- a/tests/test_decision_making/test_acquisition_maximizer.py +++ b/tests/test_decision_making/test_acquisition_maximizer.py @@ -52,7 +52,7 @@ def test_discrete_maximizer_returns_correct_point( dimensionality: int, key: KeyArray, ): - query_points = test_function.search_space.sample(1000, key=key) + query_points = test_function.generate_test_points(1000, key=key) acquisition_function = lambda x: -1.0 * test_function.evaluate(x) acquisition_vals = acquisition_function(query_points) true_max_acquisition_val = jnp.max(acquisition_vals) diff --git a/tests/test_decision_making/test_search_space.py b/tests/test_decision_making/test_search_space.py index 85f814428..49bac87ab 100644 --- a/tests/test_decision_making/test_search_space.py +++ b/tests/test_decision_making/test_search_space.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== - +from beartype.roar import BeartypeCallHintParamViolation from jax.config import config import jax.numpy as jnp import jax.random as jr @@ -62,9 +62,9 @@ def test_continuous_search_space_dtype_consistency( ], ) def test_continous_search_space_bounds_shape_consistency( - lower_bounds: Float[Array, " D"], upper_bounds: Float[Array, " D"] + lower_bounds: Float[Array, " D1"], upper_bounds: Float[Array, " D2"] ): - with pytest.raises(ValueError): + with pytest.raises((BeartypeCallHintParamViolation, ValueError)): ContinuousSearchSpace(lower_bounds=lower_bounds, upper_bounds=upper_bounds) diff --git a/tests/test_decision_making/test_test_functions/test_continuous_functions.py b/tests/test_decision_making/test_test_functions/test_continuous_functions.py index 5e13c8ce5..7b410f815 100644 --- a/tests/test_decision_making/test_test_functions/test_continuous_functions.py +++ b/tests/test_decision_making/test_test_functions/test_continuous_functions.py @@ -13,6 +13,9 @@ # limitations under the License. # ============================================================================== from jax.config import config + +config.update("jax_enable_x64", True) + import jax.numpy as jnp import jax.random as jr import pytest @@ -25,8 +28,6 @@ ) from gpjax.typing import KeyArray -config.update("jax_enable_x64", True) - def test_abstract_continuous_test_function(): with pytest.raises(TypeError): @@ -37,8 +38,10 @@ def test_abstract_continuous_test_function(): "test_function", [Quadratic(), Forrester(), LogarithmicGoldsteinPrice()] ) def test_minimizer_evaluates_to_minimum(test_function: AbstractContinuousTestFunction): + evaluated_minimizer = test_function.evaluate(test_function.minimizer) + assert evaluated_minimizer.dtype == jnp.float64 assert jnp.allclose( - test_function.evaluate(test_function.minimizer), + evaluated_minimizer, test_function.minimum, atol=1e-5, ).all() @@ -55,6 +58,7 @@ def test_correct_minimum(test_function: AbstractContinuousTestFunction, key: Key test_x = test_function.generate_test_points(100000, key) function_vals = test_function.evaluate(test_x) vals_minus_minimum = function_vals - test_function.minimum + assert function_vals.dtype == jnp.float64 assert jnp.all(vals_minus_minimum >= -1e-5) @@ -64,15 +68,16 @@ def test_correct_minimum(test_function: AbstractContinuousTestFunction, key: Key @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_consistent_dtype(test_function: AbstractContinuousTestFunction): +def test_correct_dtypes(test_function: AbstractContinuousTestFunction): minimizer = test_function.minimizer minimum = test_function.minimum dataset = test_function.generate_dataset(10, jr.PRNGKey(42)) test_x = test_function.generate_test_points(10, jr.PRNGKey(42)) - assert minimizer.dtype == minimum.dtype - assert minimizer.dtype == dataset.X.dtype - assert minimizer.dtype == dataset.y.dtype - assert minimizer.dtype == test_x.dtype + assert minimizer.dtype == jnp.float64 + assert minimum.dtype == jnp.float64 + assert dataset.X.dtype == jnp.float64 + assert dataset.y.dtype == jnp.float64 + assert test_x.dtype == jnp.float64 @pytest.mark.parametrize( From bc767f79ecccfa52901330d7ca4172e34ba8fd7d Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Sun, 20 Aug 2023 20:04:47 +0100 Subject: [PATCH 17/76] Add classes for handling posteriors during the decision making loop Added a `PosteriorHandler` class which can be used to obtain and update posteriors during the decision making loop as the number of datapoints in the training dataset changes (which is necessary for instantiating a likelihood object). Also added an `AbstractPosteriorOptimizer` abstract base class for optimizing posterior hyperparameters during the decision making loop. This allows for more customisability when optimising posteriors. Added a concrete implementation in the form of an `AdamPosteriorOptimizer` which can be used to optimize posteriors with the Adam optimizer provided by optax. --- gpjax/decision_making/__init__.py | 8 + gpjax/decision_making/posterior_handler.py | 117 +++++++ gpjax/decision_making/posterior_optimizer.py | 104 ++++++ .../test_functions/__init__.py | 5 +- .../test_functions/non_conjugate_functions.py | 90 +++++ .../test_posterior_handler.py | 311 ++++++++++++++++++ .../test_posterior_optimizer.py | 120 +++++++ .../test_non_conjugate_functions.py | 127 +++++++ 8 files changed, 881 insertions(+), 1 deletion(-) create mode 100644 gpjax/decision_making/posterior_handler.py create mode 100644 gpjax/decision_making/posterior_optimizer.py create mode 100644 gpjax/decision_making/test_functions/non_conjugate_functions.py create mode 100644 tests/test_decision_making/test_posterior_handler.py create mode 100644 tests/test_decision_making/test_posterior_optimizer.py create mode 100644 tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index 6782f6b2e..72553f4cd 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -21,6 +21,11 @@ AbstractAcquisitionMaximizer, ContinuousAcquisitionMaximizer, ) +from gpjax.decision_making.posterior_handler import PosteriorHandler +from gpjax.decision_making.posterior_optimizer import ( + AbstractPosteriorOptimizer, + AdamPosteriorOptimizer, +) from gpjax.decision_making.search_space import ( AbstractSearchSpace, ContinuousSearchSpace, @@ -35,13 +40,16 @@ __all__ = [ "AbstractAcquisitionFunctionBuilder", "AbstractAcquisitionMaximizer", + "AbstractPosteriorOptimizer", "AbstractSearchSpace", "AcquisitionFunction", + "AdamPosteriorOptimizer", "ContinuousAcquisitionMaximizer", "ContinuousSearchSpace", "AbstractContinuousTestFunction", "Forrester", "LogarithmicGoldsteinPrice", + "PosteriorHandler", "Quadratic", "ThompsonSampling", ] diff --git a/gpjax/decision_making/posterior_handler.py b/gpjax/decision_making/posterior_handler.py new file mode 100644 index 000000000..c7c4ab66f --- /dev/null +++ b/gpjax/decision_making/posterior_handler.py @@ -0,0 +1,117 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from dataclasses import dataclass + +from beartype.typing import ( + Callable, + Optional, +) + +from gpjax.dataset import Dataset +from gpjax.decision_making.posterior_optimizer import AbstractPosteriorOptimizer +from gpjax.gps import ( + AbstractLikelihood, + AbstractPosterior, + AbstractPrior, +) +from gpjax.typing import KeyArray + +LikelihoodBuilder = Callable[[int], AbstractLikelihood] +"""Type alias for likelihood builders, which take the number of datapoints as input and +return a likelihood object initialised with the given number of datapoints.""" + + +@dataclass +class PosteriorHandler: + """ + Class for handling the creation and updating of a GP posterior as new data is + observed. + + Attributes: + prior (AbstractPrior): Prior to use when forming the posterior. + likelihood_builder (LikelihoodBuilder): Function which takes the number of + datapoints as input and returns a likelihood object initialised with the given + number of datapoints. + posterior_optimizer (AbstractPosteriorOptimizer): Optimizer to use for + optimizing the posterior hyperparameters. + """ + + prior: AbstractPrior + likelihood_builder: LikelihoodBuilder + posterior_optimizer: AbstractPosteriorOptimizer + + def get_posterior( + self, dataset: Dataset, optimize: bool, key: Optional[KeyArray] = None + ) -> AbstractPosterior: + """ + Initialise (and optionally optimize) a posterior using the given dataset. + + Args: + dataset (Dataset): Dataset to get posterior for. + optimize (bool): Whether to optimize the posterior hyperparameters. + key (Optional[KeyArray]): A JAX PRNG key which is used for optimizing the posterior + hyperparameters. + + Returns: + Posterior for the given dataset. + """ + likelihood = self.likelihood_builder(dataset.n) + posterior = self.prior * likelihood + + if optimize: + if key is None: + raise ValueError( + "A key must be provided in order to optimize the posterior." + ) + posterior = self.posterior_optimizer.optimize(posterior, dataset, key) + + return posterior + + def update_posterior( + self, + dataset: Dataset, + previous_posterior: AbstractPosterior, + optimize: bool, + key: Optional[KeyArray] = None, + ) -> AbstractPosterior: + """ + Update the given posterior with the given dataset. This needs to be done when + the number of datapoints in the (training) dataset of the posterior changes, as + the `AbstractLikelihood` class requires the number of datapoints to be specified. + Hyperparameters may or may not be optimized, depending on the value of the + `optimize` parameter. Note that the updated poterior will be initialised with + the same prior hyperparameters as the previous posterior, but the likelihood + will be re-initialised with the new number of datapoints, and hyperparameters + set as in the `likelihood_builder` function. + + Args: + dataset: Dataset to get posterior for. + previous_posterior: Posterior being updated. This is supplied as one may + wish to simply increase the number of datapoints in the likelihood, without + optimizing the posterior hyperparameters, in which case the previous + posterior can be used to obtain the previously set prior hyperparameters. + optimize: Whether to optimize the posterior hyperparameters. + key: A JAX PRNG key which is used for optimizing the posterior + hyperparameters. + """ + posterior = previous_posterior.prior * self.likelihood_builder(dataset.n) + + if optimize: + if key is None: + raise ValueError( + "A key must be provided in order to optimize the posterior." + ) + posterior = self.posterior_optimizer.optimize(posterior, dataset, key) + return posterior diff --git a/gpjax/decision_making/posterior_optimizer.py b/gpjax/decision_making/posterior_optimizer.py new file mode 100644 index 000000000..160ff8856 --- /dev/null +++ b/gpjax/decision_making/posterior_optimizer.py @@ -0,0 +1,104 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import dataclass + +import optax as ox + +import gpjax as gpx +from gpjax.dataset import Dataset +from gpjax.gps import AbstractPosterior +from gpjax.objectives import AbstractObjective +from gpjax.typing import KeyArray + + +@dataclass +class AbstractPosteriorOptimizer(ABC): + """ + Abstract base class for optimizing a GP posterior. + """ + + @abstractmethod + def optimize( + self, + posterior: AbstractPosterior, + dataset: Dataset, + key: KeyArray, + ) -> AbstractPosterior: + """ + Take a posterior and corresponding dataset and optimizes the posterior + hyperparameters. + + Args: + posterior: Posterior being optimized. + dataset: Dataset used for optimizing posterior. + key: A JAX PRNG key for generating random numbers. + """ + raise NotImplementedError + + +@dataclass +class AdamPosteriorOptimizer(AbstractPosteriorOptimizer): + """ + Class for optimizing posterior hyperparameters using Adam. + + Attributes: + num_iters: The number of iterations of Adam to run. + learning_rate: The learning rate for Adam. + objective: The objective function to optimize. + """ + + num_iters: int + learning_rate: float + objective: AbstractObjective + + def __post_init__(self): + if self.num_iters < 1: + raise ValueError("num_iters must be greater than 0.") + if self.learning_rate <= 0: + raise ValueError("learning_rate must be greater than 0.") + + def optimize( + self, + posterior: AbstractPosterior, + dataset: Dataset, + key: KeyArray, + ) -> AbstractPosterior: + """ + Take a posterior and corresponding dataset and optimizes the posterior using the + Adam optimizer. + + Args: + posterior: Posterior being optimized. + dataset: Dataset used for optimizing posterior. + key: A JAX PRNG key for generating random numbers. + Returns: + Optimized posterior. + """ + opt_posterior, _ = gpx.fit( + model=posterior, + objective=self.objective, + train_data=dataset, + optim=ox.adam(learning_rate=self.learning_rate), + num_iters=self.num_iters, + safe=True, + key=key, + verbose=False, + ) + + return opt_posterior diff --git a/gpjax/decision_making/test_functions/__init__.py b/gpjax/decision_making/test_functions/__init__.py index 8fe075e1b..c5016076f 100644 --- a/gpjax/decision_making/test_functions/__init__.py +++ b/gpjax/decision_making/test_functions/__init__.py @@ -12,17 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== - from gpjax.decision_making.test_functions.continuous_functions import ( AbstractContinuousTestFunction, Forrester, LogarithmicGoldsteinPrice, Quadratic, ) +from gpjax.decision_making.test_functions.non_conjugate_functions import ( + PoissonTestFunction, +) __all__ = [ "AbstractContinuousTestFunction", "Forrester", "LogarithmicGoldsteinPrice", + "PoissonTestFunction", "Quadratic", ] diff --git a/gpjax/decision_making/test_functions/non_conjugate_functions.py b/gpjax/decision_making/test_functions/non_conjugate_functions.py new file mode 100644 index 000000000..04299b265 --- /dev/null +++ b/gpjax/decision_making/test_functions/non_conjugate_functions.py @@ -0,0 +1,90 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import abstractmethod +from dataclasses import dataclass + +import jax.numpy as jnp +import jax.random as jr +from jaxtyping import ( + Array, + Float, + Integer, +) + +from gpjax.dataset import Dataset +from gpjax.decision_making.search_space import ContinuousSearchSpace +from gpjax.typing import KeyArray + + +@dataclass +class PoissonTestFunction: + """ + Test function for GPs utilising the Poisson likelihood. Function taken from + https://docs.jaxgaussianprocesses.com/examples/poisson/#dataset. + + Attributes: + search_space (ContinuousSearchSpace): Search space for the function. + """ + + search_space: ContinuousSearchSpace = ContinuousSearchSpace( + lower_bounds=jnp.array([-2.0]), + upper_bounds=jnp.array([2.0]), + ) + + def generate_dataset(self, num_points: int, key: KeyArray) -> Dataset: + """ + Generate a toy dataset from the test function. + + Args: + num_points (int): Number of points to sample. + key (KeyArray): JAX PRNG key. + + Returns: + Dataset: Dataset of points sampled from the test function. + """ + X = self.search_space.sample(num_points=num_points, key=key) + y = self.evaluate(X) + return Dataset(X=X, y=y) + + def generate_test_points( + self, num_points: int, key: KeyArray + ) -> Float[Array, "N D"]: + """ + Generate test points from the search space of the test function. + + Args: + num_points (int): Number of points to sample. + key (KeyArray): JAX PRNG key. + + Returns: + Float[Array, 'N D']: Test points sampled from the search space. + """ + return self.search_space.sample(num_points=num_points, key=key) + + @abstractmethod + def evaluate(self, x: Float[Array, "N 1"]) -> Integer[Array, "N 1"]: + """ + Evaluate the test function at a set of points. Function taken from + https://docs.jaxgaussianprocesses.com/examples/poisson/#dataset. + + Args: + x (Float[Array, 'N D']): Points to evaluate the test function at. + + Returns: + Integer[Array, 'N 1']: Values of the test function at the points. + """ + key = jr.PRNGKey(42) + f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x + return jr.poisson(key, jnp.exp(f(x))) diff --git a/tests/test_decision_making/test_posterior_handler.py b/tests/test_decision_making/test_posterior_handler.py new file mode 100644 index 000000000..b92a59dc6 --- /dev/null +++ b/tests/test_decision_making/test_posterior_handler.py @@ -0,0 +1,311 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax.config import config + +config.update("jax_enable_x64", True) + +from beartype.typing import ( + Callable, + Union, +) +import jax.numpy as jnp +import jax.random as jr +import pytest + +from gpjax.decision_making.posterior_handler import PosteriorHandler +from gpjax.decision_making.posterior_optimizer import AdamPosteriorOptimizer +from gpjax.decision_making.test_functions import ( + Forrester, + PoissonTestFunction, +) +from gpjax.gps import Prior +from gpjax.kernels import Matern52 +from gpjax.likelihoods import ( + AbstractLikelihood, + Gaussian, + Poisson, +) +from gpjax.mean_functions import Constant +from gpjax.objectives import ( + AbstractObjective, + ConjugateMLL, + NonConjugateMLL, +) + + +def gaussian_likelihood_builder(num_datapoints: int) -> Gaussian: + return Gaussian(num_datapoints=num_datapoints) + + +def poisson_likelihood_builder(num_datapoints: int) -> Poisson: + return Poisson(num_datapoints=num_datapoints) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_get_optimized_posterior_with_no_key_raises_error(): + mean_function = Constant() + kernel = Matern52() + prior = Prior(mean_function=mean_function, kernel=kernel) + likelihood_builder = gaussian_likelihood_builder + training_objective = ConjugateMLL(negative=True) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=100, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + toy_function = Forrester() + dataset = toy_function.generate_dataset(num_points=5, key=jr.PRNGKey(42)) + with pytest.raises(ValueError): + posterior_handler.get_posterior(dataset=dataset, optimize=True) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_update_and_optimize_posterior_with_no_key_raises_error(): + mean_function = Constant() + kernel = Matern52() + prior = Prior(mean_function=mean_function, kernel=kernel) + likelihood_builder = gaussian_likelihood_builder + training_objective = ConjugateMLL(negative=True) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=100, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + toy_function = Forrester() + dataset = toy_function.generate_dataset(num_points=5, key=jr.PRNGKey(42)) + initial_posterior = posterior_handler.get_posterior(dataset=dataset, optimize=False) + with pytest.raises(ValueError): + posterior_handler.update_posterior( + dataset=dataset, previous_posterior=initial_posterior, optimize=True + ) + + +@pytest.mark.parametrize("num_datapoints", [1, 50]) +@pytest.mark.parametrize( + "likelihood_builder, training_objective, test_function", + [ + (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), + ( + poisson_likelihood_builder, + NonConjugateMLL(negative=True), + PoissonTestFunction(), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_get_posterior_no_optimization_correct_num_datapoints_and_not_optimized( + num_datapoints: int, + likelihood_builder: Callable[[int], AbstractLikelihood], + training_objective: AbstractObjective, + test_function: Union[Forrester, PoissonTestFunction], +): + mean_function = Constant(constant=jnp.array([1.0])) + kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) + prior = Prior(mean_function=mean_function, kernel=kernel) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=10, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + dataset = test_function.generate_dataset( + num_points=num_datapoints, key=jr.PRNGKey(42) + ) + posterior = posterior_handler.get_posterior(dataset=dataset, optimize=False) + assert posterior.likelihood.num_datapoints == num_datapoints + assert posterior.prior.mean_function.constant == jnp.array([1.0]) + assert posterior.prior.kernel.lengthscale == jnp.array([0.5]) + assert posterior.prior.kernel.variance == jnp.array(1.0) + + +@pytest.mark.parametrize("num_datapoints", [5, 50]) +@pytest.mark.parametrize( + "likelihood_builder, training_objective, test_function", + [ + (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), + ( + poisson_likelihood_builder, + NonConjugateMLL(negative=True), + PoissonTestFunction(), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_get_posterior_with_optimization_correct_num_datapoints_and_optimized( + num_datapoints: int, + likelihood_builder: Callable[[int], AbstractLikelihood], + training_objective: AbstractObjective, + test_function: Union[Forrester, PoissonTestFunction], +): + mean_function = Constant(constant=jnp.array([1.0])) + kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) + prior = Prior(mean_function=mean_function, kernel=kernel) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=10, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + dataset = test_function.generate_dataset( + num_points=num_datapoints, key=jr.PRNGKey(42) + ) + posterior = posterior_handler.get_posterior( + dataset=dataset, optimize=True, key=jr.PRNGKey(42) + ) + assert posterior.likelihood.num_datapoints == num_datapoints + assert posterior.prior.mean_function.constant != jnp.array([1.0]) + assert posterior.prior.kernel.lengthscale != jnp.array([0.5]) + assert posterior.prior.kernel.variance != jnp.array(1.0) + + +@pytest.mark.parametrize("initial_num_datapoints", [5, 50]) +@pytest.mark.parametrize( + "likelihood_builder, training_objective, test_function", + [ + (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), + ( + poisson_likelihood_builder, + NonConjugateMLL(negative=True), + PoissonTestFunction(), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_update_posterior_no_optimize_same_prior_parameters_and_different_num_datapoints( + initial_num_datapoints: int, + likelihood_builder: Callable[[int], AbstractLikelihood], + training_objective: AbstractObjective, + test_function: Union[Forrester, PoissonTestFunction], +): + mean_function = Constant(constant=jnp.array([1.0])) + kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) + prior = Prior(mean_function=mean_function, kernel=kernel) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=100, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + initial_dataset = test_function.generate_dataset( + num_points=initial_num_datapoints, key=jr.PRNGKey(42) + ) + initial_posterior = posterior_handler.get_posterior( + dataset=initial_dataset, optimize=False + ) + updated_dataset = initial_dataset + test_function.generate_dataset( + num_points=1, key=jr.PRNGKey(42) + ) + assert updated_dataset.n == initial_dataset.n + 1 + updated_posterior = posterior_handler.update_posterior( + dataset=updated_dataset, previous_posterior=initial_posterior, optimize=False + ) + assert ( + updated_posterior.prior.kernel.lengthscale + == initial_posterior.prior.kernel.lengthscale + ) + assert ( + updated_posterior.prior.kernel.variance + == initial_posterior.prior.kernel.variance + ) + assert ( + updated_posterior.prior.mean_function.constant + == initial_posterior.prior.mean_function.constant + ) + assert updated_posterior.likelihood.num_datapoints == updated_dataset.n + + +@pytest.mark.parametrize("initial_num_datapoints", [5, 50]) +@pytest.mark.parametrize( + "likelihood_builder, training_objective, test_function", + [ + (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), + ( + poisson_likelihood_builder, + NonConjugateMLL(negative=True), + PoissonTestFunction(), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_update_posterior_with_optimization_updated_prior_parameters_and_different_num_datapoints( + initial_num_datapoints: int, + likelihood_builder: Callable[[int], AbstractLikelihood], + training_objective: AbstractObjective, + test_function: Union[Forrester, PoissonTestFunction], +): + mean_function = Constant(constant=jnp.array([1.0])) + kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) + prior = Prior(mean_function=mean_function, kernel=kernel) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=100, learning_rate=0.01, objective=training_objective + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + posterior_optimizer=posterior_optimizer, + ) + initial_dataset = test_function.generate_dataset( + num_points=initial_num_datapoints, key=jr.PRNGKey(42) + ) + initial_posterior = posterior_handler.get_posterior( + dataset=initial_dataset, optimize=False + ) + updated_dataset = initial_dataset + test_function.generate_dataset( + num_points=1, key=jr.PRNGKey(42) + ) + assert updated_dataset.n == initial_dataset.n + 1 + updated_posterior = posterior_handler.update_posterior( + dataset=updated_dataset, + previous_posterior=initial_posterior, + optimize=True, + key=jr.PRNGKey(42), + ) + assert ( + updated_posterior.prior.kernel.lengthscale + != initial_posterior.prior.kernel.lengthscale + ) + assert ( + updated_posterior.prior.kernel.variance + != initial_posterior.prior.kernel.variance + ) + assert ( + updated_posterior.prior.mean_function.constant + != initial_posterior.prior.mean_function.constant + ) + assert updated_posterior.likelihood.num_datapoints == updated_dataset.n diff --git a/tests/test_decision_making/test_posterior_optimizer.py b/tests/test_decision_making/test_posterior_optimizer.py new file mode 100644 index 000000000..c37cad4b5 --- /dev/null +++ b/tests/test_decision_making/test_posterior_optimizer.py @@ -0,0 +1,120 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax.config import config + +config.update("jax_enable_x64", True) + +from beartype.typing import ( + Callable, + Union, +) +import jax.numpy as jnp +import jax.random as jr +import pytest + +from gpjax.decision_making.posterior_optimizer import ( + AbstractPosteriorOptimizer, + AdamPosteriorOptimizer, +) +from gpjax.decision_making.test_functions import ( + Forrester, + PoissonTestFunction, +) +from gpjax.gps import Prior +from gpjax.kernels import Matern52 +from gpjax.likelihoods import ( + AbstractLikelihood, + Gaussian, + Poisson, +) +from gpjax.mean_functions import Constant +from gpjax.objectives import ( + AbstractObjective, + ConjugateMLL, + NonConjugateMLL, +) + + +def gaussian_likelihood_builder(num_datapoints: int) -> Gaussian: + return Gaussian(num_datapoints=num_datapoints) + + +def poisson_likelihood_builder(num_datapoints: int) -> Poisson: + return Poisson(num_datapoints=num_datapoints) + + +def test_abstract_posterior_optimizer(): + with pytest.raises(TypeError): + AbstractPosteriorOptimizer() + + +@pytest.mark.parametrize("num_iters", [0, -1, -10]) +def test_adam_posterior_optimizer_erroneous_num_iters_raises_error(num_iters: int): + with pytest.raises(ValueError): + objective = ConjugateMLL(negative=True) + AdamPosteriorOptimizer( + num_iters=num_iters, learning_rate=0.01, objective=objective + ) + + +@pytest.mark.parametrize("learning_rate", [0.0, -1.0, -10.0]) +def test_adam_posterior_optimizer_erroneous_learning_rate_raises_error( + learning_rate: float, +): + with pytest.raises(ValueError): + objective = ConjugateMLL(negative=True) + AdamPosteriorOptimizer( + num_iters=10, learning_rate=learning_rate, objective=objective + ) + + +@pytest.mark.parametrize("num_datapoints", [5, 50]) +@pytest.mark.parametrize( + "likelihood_builder, training_objective, test_function", + [ + (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), + ( + poisson_likelihood_builder, + NonConjugateMLL(negative=True), + PoissonTestFunction(), + ), + ], +) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_adam_posterior_optimize( + num_datapoints: int, + likelihood_builder: Callable[[int], AbstractLikelihood], + training_objective: AbstractObjective, + test_function: Union[Forrester, PoissonTestFunction], +): + mean_function = Constant(constant=jnp.array([1.0])) + kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) + prior = Prior(mean_function=mean_function, kernel=kernel) + posterior_optimizer = AdamPosteriorOptimizer( + num_iters=10, learning_rate=0.01, objective=training_objective + ) + dataset = test_function.generate_dataset( + num_points=num_datapoints, key=jr.PRNGKey(42) + ) + initial_posterior = prior * likelihood_builder(num_datapoints) + optimized_posterior = posterior_optimizer.optimize( + posterior=initial_posterior, dataset=dataset, key=jr.PRNGKey(42) + ) + assert type(optimized_posterior) == type(initial_posterior) + assert training_objective(optimized_posterior, dataset) < training_objective( + initial_posterior, dataset + ) # Ensure optimization reduces training objective diff --git a/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py b/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py new file mode 100644 index 000000000..837abdbfd --- /dev/null +++ b/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py @@ -0,0 +1,127 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax.config import config + +config.update("jax_enable_x64", True) + +import jax.numpy as jnp +import jax.random as jr +import pytest + +from gpjax.decision_making.test_functions import PoissonTestFunction +from gpjax.typing import KeyArray + + +@pytest.mark.parametrize("test_function", [PoissonTestFunction()]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_correct_dtypes(test_function: PoissonTestFunction): + dataset = test_function.generate_dataset(10, jr.PRNGKey(42)) + test_x = test_function.generate_test_points(10, jr.PRNGKey(42)) + assert dataset.X.dtype == jnp.float64 + assert dataset.y.dtype == jnp.integer + assert test_x.dtype == jnp.float64 + + +@pytest.mark.parametrize( + "test_function, dimensionality", + [(PoissonTestFunction(), 1)], +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_test_points_shape( + test_function: PoissonTestFunction, dimensionality: int, num_samples: int +): + test_X = test_function.generate_test_points(num_samples, jr.PRNGKey(42)) + assert test_X.shape == (num_samples, dimensionality) + + +@pytest.mark.parametrize( + "test_function, dimensionality", + [(PoissonTestFunction(), 1)], +) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_dataset_shapes( + test_function: PoissonTestFunction, dimensionality: int, num_samples: int +): + dataset = test_function.generate_dataset(num_samples, jr.PRNGKey(42)) + assert dataset.X.shape == (num_samples, dimensionality) + assert dataset.y.shape == (num_samples, 1) + + +@pytest.mark.parametrize("test_function", [PoissonTestFunction()]) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_same_key_same_dataset( + test_function: PoissonTestFunction, num_samples: int, key: KeyArray +): + dataset_one = test_function.generate_dataset(num_samples, key) + dataset_two = test_function.generate_dataset(num_samples, key) + assert jnp.equal(dataset_one.X, dataset_two.X).all() + assert jnp.equal(dataset_one.y, dataset_two.y).all() + + +@pytest.mark.parametrize("test_function", [PoissonTestFunction()]) +@pytest.mark.parametrize("num_samples", [10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_different_key_different_dataset( + test_function: PoissonTestFunction, num_samples: int, key: KeyArray +): + dataset_one = test_function.generate_dataset(num_samples, key) + key, _ = jr.split(key) + dataset_two = test_function.generate_dataset(num_samples, key) + assert not jnp.equal(dataset_one.X, dataset_two.X).all() + assert not jnp.equal(dataset_one.y, dataset_two.y).all() + + +@pytest.mark.parametrize("test_function", [PoissonTestFunction()]) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_same_key_same_test_points( + test_function: PoissonTestFunction, num_samples: int, key: KeyArray +): + test_points_one = test_function.generate_test_points(num_samples, key) + test_points_two = test_function.generate_test_points(num_samples, key) + assert jnp.equal(test_points_one, test_points_two).all() + + +@pytest.mark.parametrize("test_function", [PoissonTestFunction()]) +@pytest.mark.parametrize("num_samples", [1, 10, 100]) +@pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10)]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_different_key_different_test_points( + test_function: PoissonTestFunction, num_samples: int, key: KeyArray +): + test_points_one = test_function.generate_test_points(num_samples, key) + key, _ = jr.split(key) + test_points_two = test_function.generate_test_points(num_samples, key) + assert not jnp.equal(test_points_one, test_points_two).all() From 797766b5cc5c2dd71f703a939614a02b47ac8a02 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Sun, 20 Aug 2023 20:36:16 +0100 Subject: [PATCH 18/76] Attempt to fix failing documentation test --- gpjax/decision_making/test_functions/non_conjugate_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpjax/decision_making/test_functions/non_conjugate_functions.py b/gpjax/decision_making/test_functions/non_conjugate_functions.py index 04299b265..94fa4ecb1 100644 --- a/gpjax/decision_making/test_functions/non_conjugate_functions.py +++ b/gpjax/decision_making/test_functions/non_conjugate_functions.py @@ -38,7 +38,7 @@ class PoissonTestFunction: search_space (ContinuousSearchSpace): Search space for the function. """ - search_space: ContinuousSearchSpace = ContinuousSearchSpace( + search_space = ContinuousSearchSpace( lower_bounds=jnp.array([-2.0]), upper_bounds=jnp.array([2.0]), ) From 1bc619f2f1cd17fcdd0ed16bff38400fe09e5df9 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Tue, 22 Aug 2023 15:54:47 +0100 Subject: [PATCH 19/76] Remove `PosteriorOptimizer` classes Removed the `PosteriorOptimizer` classes and included posterior optimization logic in the `PosteriorHandler` class. --- gpjax/decision_making/__init__.py | 6 - gpjax/decision_making/posterior_handler.py | 54 ++++++-- gpjax/decision_making/posterior_optimizer.py | 104 --------------- .../test_posterior_handler.py | 97 ++++++++------ .../test_posterior_optimizer.py | 120 ------------------ 5 files changed, 107 insertions(+), 274 deletions(-) delete mode 100644 gpjax/decision_making/posterior_optimizer.py delete mode 100644 tests/test_decision_making/test_posterior_optimizer.py diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index 72553f4cd..c3ff92262 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -22,10 +22,6 @@ ContinuousAcquisitionMaximizer, ) from gpjax.decision_making.posterior_handler import PosteriorHandler -from gpjax.decision_making.posterior_optimizer import ( - AbstractPosteriorOptimizer, - AdamPosteriorOptimizer, -) from gpjax.decision_making.search_space import ( AbstractSearchSpace, ContinuousSearchSpace, @@ -40,10 +36,8 @@ __all__ = [ "AbstractAcquisitionFunctionBuilder", "AbstractAcquisitionMaximizer", - "AbstractPosteriorOptimizer", "AbstractSearchSpace", "AcquisitionFunction", - "AdamPosteriorOptimizer", "ContinuousAcquisitionMaximizer", "ContinuousSearchSpace", "AbstractContinuousTestFunction", diff --git a/gpjax/decision_making/posterior_handler.py b/gpjax/decision_making/posterior_handler.py index c7c4ab66f..06b672172 100644 --- a/gpjax/decision_making/posterior_handler.py +++ b/gpjax/decision_making/posterior_handler.py @@ -18,14 +18,16 @@ Callable, Optional, ) +import optax as ox +import gpjax as gpx from gpjax.dataset import Dataset -from gpjax.decision_making.posterior_optimizer import AbstractPosteriorOptimizer from gpjax.gps import ( AbstractLikelihood, AbstractPosterior, AbstractPrior, ) +from gpjax.objectives import AbstractObjective from gpjax.typing import KeyArray LikelihoodBuilder = Callable[[int], AbstractLikelihood] @@ -44,13 +46,23 @@ class PosteriorHandler: likelihood_builder (LikelihoodBuilder): Function which takes the number of datapoints as input and returns a likelihood object initialised with the given number of datapoints. - posterior_optimizer (AbstractPosteriorOptimizer): Optimizer to use for - optimizing the posterior hyperparameters. + optimization_objective (AbstractObjective): Objective to use for optimizing the + posterior hyperparameters. + optimizer (ox.GradientTransformation): Optax optimizer to use for optimizing the + posterior hyperparameters. + num_optimization_iterations (int): Number of iterations to optimize + the posterior hyperparameters for. """ prior: AbstractPrior likelihood_builder: LikelihoodBuilder - posterior_optimizer: AbstractPosteriorOptimizer + optimization_objective: AbstractObjective + optimizer: ox.GradientTransformation + num_optimization_iters: int + + def __post_init__(self): + if self.num_optimization_iters < 1: + raise ValueError("num_optimization_iters must be greater than 0.") def get_posterior( self, dataset: Dataset, optimize: bool, key: Optional[KeyArray] = None @@ -67,15 +79,14 @@ def get_posterior( Returns: Posterior for the given dataset. """ - likelihood = self.likelihood_builder(dataset.n) - posterior = self.prior * likelihood + posterior = self.prior * self.likelihood_builder(dataset.n) if optimize: if key is None: raise ValueError( "A key must be provided in order to optimize the posterior." ) - posterior = self.posterior_optimizer.optimize(posterior, dataset, key) + posterior = self._optimize_posterior(posterior, dataset, key) return posterior @@ -113,5 +124,32 @@ def update_posterior( raise ValueError( "A key must be provided in order to optimize the posterior." ) - posterior = self.posterior_optimizer.optimize(posterior, dataset, key) + posterior = self._optimize_posterior(posterior, dataset, key) return posterior + + def _optimize_posterior( + self, posterior: AbstractPosterior, dataset: Dataset, key: KeyArray + ) -> AbstractPosterior: + """ + Takes a posterior and corresponding dataset and optimizes the posterior using the + GPJax `fit` method. + + Args: + posterior: Posterior being optimized. + dataset: Dataset used for optimizing posterior. + key: A JAX PRNG key for generating random numbers. + Returns: + Optimized posterior. + """ + opt_posterior, _ = gpx.fit( + model=posterior, + objective=self.optimization_objective, + train_data=dataset, + optim=self.optimizer, + num_iters=self.num_optimization_iters, + safe=True, + key=key, + verbose=False, + ) + + return opt_posterior diff --git a/gpjax/decision_making/posterior_optimizer.py b/gpjax/decision_making/posterior_optimizer.py deleted file mode 100644 index 160ff8856..000000000 --- a/gpjax/decision_making/posterior_optimizer.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -from abc import ( - ABC, - abstractmethod, -) -from dataclasses import dataclass - -import optax as ox - -import gpjax as gpx -from gpjax.dataset import Dataset -from gpjax.gps import AbstractPosterior -from gpjax.objectives import AbstractObjective -from gpjax.typing import KeyArray - - -@dataclass -class AbstractPosteriorOptimizer(ABC): - """ - Abstract base class for optimizing a GP posterior. - """ - - @abstractmethod - def optimize( - self, - posterior: AbstractPosterior, - dataset: Dataset, - key: KeyArray, - ) -> AbstractPosterior: - """ - Take a posterior and corresponding dataset and optimizes the posterior - hyperparameters. - - Args: - posterior: Posterior being optimized. - dataset: Dataset used for optimizing posterior. - key: A JAX PRNG key for generating random numbers. - """ - raise NotImplementedError - - -@dataclass -class AdamPosteriorOptimizer(AbstractPosteriorOptimizer): - """ - Class for optimizing posterior hyperparameters using Adam. - - Attributes: - num_iters: The number of iterations of Adam to run. - learning_rate: The learning rate for Adam. - objective: The objective function to optimize. - """ - - num_iters: int - learning_rate: float - objective: AbstractObjective - - def __post_init__(self): - if self.num_iters < 1: - raise ValueError("num_iters must be greater than 0.") - if self.learning_rate <= 0: - raise ValueError("learning_rate must be greater than 0.") - - def optimize( - self, - posterior: AbstractPosterior, - dataset: Dataset, - key: KeyArray, - ) -> AbstractPosterior: - """ - Take a posterior and corresponding dataset and optimizes the posterior using the - Adam optimizer. - - Args: - posterior: Posterior being optimized. - dataset: Dataset used for optimizing posterior. - key: A JAX PRNG key for generating random numbers. - Returns: - Optimized posterior. - """ - opt_posterior, _ = gpx.fit( - model=posterior, - objective=self.objective, - train_data=dataset, - optim=ox.adam(learning_rate=self.learning_rate), - num_iters=self.num_iters, - safe=True, - key=key, - verbose=False, - ) - - return opt_posterior diff --git a/tests/test_decision_making/test_posterior_handler.py b/tests/test_decision_making/test_posterior_handler.py index b92a59dc6..71bf9a4b4 100644 --- a/tests/test_decision_making/test_posterior_handler.py +++ b/tests/test_decision_making/test_posterior_handler.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config config.update("jax_enable_x64", True) @@ -22,10 +22,10 @@ ) import jax.numpy as jnp import jax.random as jr +import optax as ox import pytest from gpjax.decision_making.posterior_handler import PosteriorHandler -from gpjax.decision_making.posterior_optimizer import AdamPosteriorOptimizer from gpjax.decision_making.test_functions import ( Forrester, PoissonTestFunction, @@ -53,6 +53,25 @@ def poisson_likelihood_builder(num_datapoints: int) -> Poisson: return Poisson(num_datapoints=num_datapoints) +@pytest.mark.parametrize("num_optimization_iters", [0, -1, -10]) +def test_posterior_handler_erroneous_num_optimization_iterations_raises_error( + num_optimization_iters: int, +): + mean_function = Constant() + kernel = Matern52() + prior = Prior(mean_function=mean_function, kernel=kernel) + likelihood_builder = gaussian_likelihood_builder + training_objective = ConjugateMLL(negative=True) + with pytest.raises(ValueError): + PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=num_optimization_iters, + ) + + @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort @@ -62,13 +81,12 @@ def test_get_optimized_posterior_with_no_key_raises_error(): prior = Prior(mean_function=mean_function, kernel=kernel) likelihood_builder = gaussian_likelihood_builder training_objective = ConjugateMLL(negative=True) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=100, learning_rate=0.01, objective=training_objective - ) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) toy_function = Forrester() dataset = toy_function.generate_dataset(num_points=5, key=jr.PRNGKey(42)) @@ -85,13 +103,12 @@ def test_update_and_optimize_posterior_with_no_key_raises_error(): prior = Prior(mean_function=mean_function, kernel=kernel) likelihood_builder = gaussian_likelihood_builder training_objective = ConjugateMLL(negative=True) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=100, learning_rate=0.01, objective=training_objective - ) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) toy_function = Forrester() dataset = toy_function.generate_dataset(num_points=5, key=jr.PRNGKey(42)) @@ -126,13 +143,12 @@ def test_get_posterior_no_optimization_correct_num_datapoints_and_not_optimized( mean_function = Constant(constant=jnp.array([1.0])) kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) prior = Prior(mean_function=mean_function, kernel=kernel) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=10, learning_rate=0.01, objective=training_objective - ) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) dataset = test_function.generate_dataset( num_points=num_datapoints, key=jr.PRNGKey(42) @@ -168,24 +184,27 @@ def test_get_posterior_with_optimization_correct_num_datapoints_and_optimized( mean_function = Constant(constant=jnp.array([1.0])) kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) prior = Prior(mean_function=mean_function, kernel=kernel) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=10, learning_rate=0.01, objective=training_objective - ) + non_optimized_posterior = prior * likelihood_builder(num_datapoints) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) dataset = test_function.generate_dataset( num_points=num_datapoints, key=jr.PRNGKey(42) ) - posterior = posterior_handler.get_posterior( + optimized_posterior = posterior_handler.get_posterior( dataset=dataset, optimize=True, key=jr.PRNGKey(42) ) - assert posterior.likelihood.num_datapoints == num_datapoints - assert posterior.prior.mean_function.constant != jnp.array([1.0]) - assert posterior.prior.kernel.lengthscale != jnp.array([0.5]) - assert posterior.prior.kernel.variance != jnp.array(1.0) + assert optimized_posterior.likelihood.num_datapoints == num_datapoints + assert optimized_posterior.prior.mean_function.constant != jnp.array([1.0]) + assert optimized_posterior.prior.kernel.lengthscale != jnp.array([0.5]) + assert optimized_posterior.prior.kernel.variance != jnp.array(1.0) + assert training_objective(optimized_posterior, dataset) < training_objective( + non_optimized_posterior, dataset + ) # Ensure optimization reduces training objective @pytest.mark.parametrize("initial_num_datapoints", [5, 50]) @@ -212,13 +231,12 @@ def test_update_posterior_no_optimize_same_prior_parameters_and_different_num_da mean_function = Constant(constant=jnp.array([1.0])) kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) prior = Prior(mean_function=mean_function, kernel=kernel) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=100, learning_rate=0.01, objective=training_objective - ) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) initial_dataset = test_function.generate_dataset( num_points=initial_num_datapoints, key=jr.PRNGKey(42) @@ -272,13 +290,12 @@ def test_update_posterior_with_optimization_updated_prior_parameters_and_differe mean_function = Constant(constant=jnp.array([1.0])) kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) prior = Prior(mean_function=mean_function, kernel=kernel) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=100, learning_rate=0.01, objective=training_objective - ) posterior_handler = PosteriorHandler( prior=prior, likelihood_builder=likelihood_builder, - posterior_optimizer=posterior_optimizer, + optimization_objective=training_objective, + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=10, ) initial_dataset = test_function.generate_dataset( num_points=initial_num_datapoints, key=jr.PRNGKey(42) @@ -290,22 +307,30 @@ def test_update_posterior_with_optimization_updated_prior_parameters_and_differe num_points=1, key=jr.PRNGKey(42) ) assert updated_dataset.n == initial_dataset.n + 1 - updated_posterior = posterior_handler.update_posterior( + non_optimized_updated_posterior = posterior_handler.update_posterior( + dataset=updated_dataset, previous_posterior=initial_posterior, optimize=False + ) + optimized_updated_posterior = posterior_handler.update_posterior( dataset=updated_dataset, previous_posterior=initial_posterior, optimize=True, key=jr.PRNGKey(42), ) assert ( - updated_posterior.prior.kernel.lengthscale + optimized_updated_posterior.prior.kernel.lengthscale != initial_posterior.prior.kernel.lengthscale ) assert ( - updated_posterior.prior.kernel.variance + optimized_updated_posterior.prior.kernel.variance != initial_posterior.prior.kernel.variance ) assert ( - updated_posterior.prior.mean_function.constant + optimized_updated_posterior.prior.mean_function.constant != initial_posterior.prior.mean_function.constant ) - assert updated_posterior.likelihood.num_datapoints == updated_dataset.n + assert optimized_updated_posterior.likelihood.num_datapoints == updated_dataset.n + assert training_objective( + optimized_updated_posterior, updated_dataset + ) < training_objective( + non_optimized_updated_posterior, updated_dataset + ) # Ensure optimization reduces training objective diff --git a/tests/test_decision_making/test_posterior_optimizer.py b/tests/test_decision_making/test_posterior_optimizer.py deleted file mode 100644 index c37cad4b5..000000000 --- a/tests/test_decision_making/test_posterior_optimizer.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -from jax.config import config - -config.update("jax_enable_x64", True) - -from beartype.typing import ( - Callable, - Union, -) -import jax.numpy as jnp -import jax.random as jr -import pytest - -from gpjax.decision_making.posterior_optimizer import ( - AbstractPosteriorOptimizer, - AdamPosteriorOptimizer, -) -from gpjax.decision_making.test_functions import ( - Forrester, - PoissonTestFunction, -) -from gpjax.gps import Prior -from gpjax.kernels import Matern52 -from gpjax.likelihoods import ( - AbstractLikelihood, - Gaussian, - Poisson, -) -from gpjax.mean_functions import Constant -from gpjax.objectives import ( - AbstractObjective, - ConjugateMLL, - NonConjugateMLL, -) - - -def gaussian_likelihood_builder(num_datapoints: int) -> Gaussian: - return Gaussian(num_datapoints=num_datapoints) - - -def poisson_likelihood_builder(num_datapoints: int) -> Poisson: - return Poisson(num_datapoints=num_datapoints) - - -def test_abstract_posterior_optimizer(): - with pytest.raises(TypeError): - AbstractPosteriorOptimizer() - - -@pytest.mark.parametrize("num_iters", [0, -1, -10]) -def test_adam_posterior_optimizer_erroneous_num_iters_raises_error(num_iters: int): - with pytest.raises(ValueError): - objective = ConjugateMLL(negative=True) - AdamPosteriorOptimizer( - num_iters=num_iters, learning_rate=0.01, objective=objective - ) - - -@pytest.mark.parametrize("learning_rate", [0.0, -1.0, -10.0]) -def test_adam_posterior_optimizer_erroneous_learning_rate_raises_error( - learning_rate: float, -): - with pytest.raises(ValueError): - objective = ConjugateMLL(negative=True) - AdamPosteriorOptimizer( - num_iters=10, learning_rate=learning_rate, objective=objective - ) - - -@pytest.mark.parametrize("num_datapoints", [5, 50]) -@pytest.mark.parametrize( - "likelihood_builder, training_objective, test_function", - [ - (gaussian_likelihood_builder, ConjugateMLL(negative=True), Forrester()), - ( - poisson_likelihood_builder, - NonConjugateMLL(negative=True), - PoissonTestFunction(), - ), - ], -) -@pytest.mark.filterwarnings( - "ignore::UserWarning" -) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_adam_posterior_optimize( - num_datapoints: int, - likelihood_builder: Callable[[int], AbstractLikelihood], - training_objective: AbstractObjective, - test_function: Union[Forrester, PoissonTestFunction], -): - mean_function = Constant(constant=jnp.array([1.0])) - kernel = Matern52(lengthscale=jnp.array([0.5]), variance=jnp.array(1.0)) - prior = Prior(mean_function=mean_function, kernel=kernel) - posterior_optimizer = AdamPosteriorOptimizer( - num_iters=10, learning_rate=0.01, objective=training_objective - ) - dataset = test_function.generate_dataset( - num_points=num_datapoints, key=jr.PRNGKey(42) - ) - initial_posterior = prior * likelihood_builder(num_datapoints) - optimized_posterior = posterior_optimizer.optimize( - posterior=initial_posterior, dataset=dataset, key=jr.PRNGKey(42) - ) - assert type(optimized_posterior) == type(initial_posterior) - assert training_objective(optimized_posterior, dataset) < training_objective( - initial_posterior, dataset - ) # Ensure optimization reduces training objective From 67d1b1f3c2816d15143a872cdf9044e4a54f4a44 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Tue, 22 Aug 2023 22:18:10 +0200 Subject: [PATCH 20/76] Finalise benchmarking --- .github/workflows/benchmarks.yml | 52 ++++++++++++ .gitignore | 2 +- .../Toms-MacBook-Air-2.local/machine.json | 9 -- poetry.lock | 84 ++++++++++++++++++- pyproject.toml | 1 + 5 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/benchmarks.yml delete mode 100644 benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 000000000..94235c805 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,52 @@ +name: Benchmarks + +on: + push: + branches: [main] + schedule: + - cron: "0 2 * * *" + workflow_dispatch: + +jobs: + run-benchmarks: + name: Run benchmarks + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: ["ubuntu-latest"] + python-version: ["3.8"] + steps: + - name: Checkout the branch + uses: actions/checkout@v3.5.2 + with: + fetch-depth: 1 + - name: Install Poetry + uses: snok/install-poetry@v1.3.3 + with: + version: 1.4.0 + + # Configure Poetry to use the virtual environment in the project + - name: Setup Poetry + run: | + poetry config virtualenvs.in-project true + + - name: Install dependencies + run: | + poetry install --all-extras --with dev + pip install virtualenv + + - name: Set asv machine + run: asv machine --yes + + - name: Run benchmarks + uses: | + cd benchmarks + asv run --python PYTHON + asv publish + + - name: Deploy to benchmarks branch + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./.asv/html + publish_branch: benchmarks diff --git a/.gitignore b/.gitignore index a86c88bbb..3b8bb1b11 100644 --- a/.gitignore +++ b/.gitignore @@ -151,4 +151,4 @@ package.json package-lock.json node_modules/ -docs/api +docs/api \ No newline at end of file diff --git a/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json b/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json deleted file mode 100644 index 0222d4bdb..000000000 --- a/benchmarks/.asv/results/Toms-MacBook-Air-2.local/machine.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "arch": "arm64", - "cpu": "Apple M1", - "machine": "Toms-MacBook-Air-2.local", - "num_cpu": "8", - "os": "Darwin 22.3.0", - "ram": "8589934592", - "version": 1 -} \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 114a0fcd9..a284f3df1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -119,6 +119,39 @@ python-versions = "*" six = ">=1.6.1,<2.0" wheel = ">=0.23.0,<1.0" +[[package]] +name = "asv" +version = "0.6.0" +description = "Airspeed Velocity: A simple Python history benchmarking tool" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +asv-runner = ">=v0.0.9" +colorama = {version = "*", markers = "os_name == \"nt\""} +json5 = "*" +pympler = {version = "*", markers = "platform_python_implementation != \"PyPy\""} +pyyaml = {version = "*", markers = "platform_python_implementation != \"PyPy\""} +tabulate = "*" + +[package.extras] +dev = ["isort (>=5.11.5)", "ruff"] +doc = ["sphinx", "sphinx_bootstrap_theme"] +hg = ["python-hglib"] +test = ["feedparser", "filelock", "numpy", "pytest", "pytest-rerunfailures", "pytest-rerunfailures (>=10.0)", "pytest-timeout", "pytest-xdist", "python-hglib", "rpy2", "scipy", "selenium", "virtualenv"] + +[[package]] +name = "asv-runner" +version = "0.0.9" +description = "Core Python benchmark code for ASV" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "myst-parser (>=2)", "sphinx", "sphinx-autobuild", "sphinx-autodoc2 (>=0.4.2)", "sphinx-contributors", "sphinx-copybutton", "sphinx-design", "sphinxcontrib-spelling"] + [[package]] name = "async-timeout" version = "4.0.2" @@ -1013,6 +1046,17 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "json5" +version = "0.9.14" +description = "A Python implementation of the JSON5 data format." +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +dev = ["hypothesis"] + [[package]] name = "jsonschema" version = "4.17.3" @@ -2063,6 +2107,14 @@ python-versions = ">=3.7" markdown = ">=3.2" pyyaml = "*" +[[package]] +name = "pympler" +version = "1.0.1" +description = "A development tool to measure, monitor and analyze the memory behavior of Python objects." +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "pypandoc" version = "1.11" @@ -2552,6 +2604,17 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tensorflow-probability" version = "0.19.0" @@ -2893,7 +2956,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.8,<3.12" -content-hash = "cdd5dbb43af30c1222d750e528eaab84c7e45eed2ce4e90b2b5f0422a3930eac" +content-hash = "7e057e35bc4438a123be1a7479ae6383b1ae10129ba6b94690b0ee001137aa10" [metadata.files] absl-py = [ @@ -3021,6 +3084,13 @@ astunparse = [ {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, ] +asv = [ + {file = "asv-0.6.0.tar.gz", hash = "sha256:9afce3008094209b7e87b7b880bc6b8f2da303fdc6dd665c7be9f1057ecd5753"}, +] +asv-runner = [ + {file = "asv_runner-0.0.9-py3-none-any.whl", hash = "sha256:ef655b451fbe6805b7981ded72d8ac38a8158fa37c770140e1bc6e992e96e5bb"}, + {file = "asv_runner-0.0.9.tar.gz", hash = "sha256:4531cf5677bb19e5bd91d9789378b057037bd17e0d9043621b7ede9eaac88f97"}, +] async-timeout = [ {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, @@ -3693,6 +3763,10 @@ joblib = [ {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"}, {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"}, ] +json5 = [ + {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, + {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, +] jsonschema = [ {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, @@ -4499,6 +4573,10 @@ pymdown-extensions = [ {file = "pymdown_extensions-9.11-py3-none-any.whl", hash = "sha256:a499191d8d869f30339de86fcf072a787e86c42b6f16f280f5c2cf174182b7f3"}, {file = "pymdown_extensions-9.11.tar.gz", hash = "sha256:f7e86c1d3981f23d9dc43294488ecb54abadd05b0be4bf8f0e15efc90f7853ff"}, ] +pympler = [ + {file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"}, + {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, +] pypandoc = [ {file = "pypandoc-1.11-py3-none-any.whl", hash = "sha256:b260596934e9cfc6513056110a7c8600171d414f90558bf4407e68b209be8007"}, {file = "pypandoc-1.11.tar.gz", hash = "sha256:7f6d68db0e57e0f6961bec2190897118c4d305fc2d31c22cd16037f22ee084a5"}, @@ -5020,6 +5098,10 @@ stack-data = [ {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, ] +tabulate = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] tensorflow-probability = [ {file = "tensorflow_probability-0.19.0-py2.py3-none-any.whl", hash = "sha256:ee70967fbd52b09e9c5ec148a9437c4cf3f9e9d689cdca400a1bc921f21cdcac"}, ] diff --git a/pyproject.toml b/pyproject.toml index db3bd20f0..ebcb70aa7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ pre-commit = "^3.2.2" nbstripout = "^0.6.1" pydocstyle = "^6.3.0" codespell = "^2.2.4" +asv = "^0.6.0" [tool.poetry.group.docs.dependencies] From 3bf2604b2be0f87232fe8a09c920114265286dfb Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Tue, 22 Aug 2023 22:26:58 +0200 Subject: [PATCH 21/76] Format --- benchmarks/.asv/results/benchmarks.json | 728 ++++++++++++++++++++++++ benchmarks/asv.conf.json | 88 +-- benchmarks/kernels.py | 3 +- benchmarks/linops.py | 5 +- benchmarks/objectives.py | 5 +- benchmarks/predictions.py | 10 +- benchmarks/sparse.py | 5 +- 7 files changed, 749 insertions(+), 95 deletions(-) create mode 100644 benchmarks/.asv/results/benchmarks.json diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json new file mode 100644 index 000000000..fd6f2304e --- /dev/null +++ b/benchmarks/.asv/results/benchmarks.json @@ -0,0 +1,728 @@ +{ + "kernels.ArcCosine.time_covfunc_call": { + "code": "class ArcCosine:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.ArcCosine.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "f923a5feb1913469c66f702d89993918b418cc376b993df1cb7b974c3af01dfe", + "warmup_time": -1 + }, + "kernels.Linear.time_covfunc_call": { + "code": "class Linear:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Linear(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Linear.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "937688fe2a0aa44886c8c5856202502b9c82d2043d1034bf1c5984d73999b6b3", + "warmup_time": -1 + }, + "kernels.Matern12.time_covfunc_call": { + "code": "class Matern12:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern12(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Matern12.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "847a1c25403643211b2dbe93ac755ad2ddcd5da5e2b53136841d6ab99cc12699", + "warmup_time": -1 + }, + "kernels.Matern32.time_covfunc_call": { + "code": "class Matern32:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern32(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Matern32.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "a520e46707f3b3181f63c1e1a372e9e6cea4d8bcfc1d24ab4b7f40ff1dadf171", + "warmup_time": -1 + }, + "kernels.Matern52.time_covfunc_call": { + "code": "class Matern52:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern52(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Matern52.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "179838852e999abcac68e90c141724342d0b4a25656f5ea7be6409ac9205b91f", + "warmup_time": -1 + }, + "kernels.Polynomial.time_covfunc_call": { + "code": "class Polynomial:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Polynomial(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.Polynomial.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "67213fe983f9f09d6213609250aab0870f9b652c1fb08e07f68581af193365d5", + "warmup_time": -1 + }, + "kernels.PoweredExponential.time_covfunc_call": { + "code": "class PoweredExponential:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.PoweredExponential.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "2da6e3291d5e431eed969aaba40c4b42f226ebad022e3ea56b257ab2e2e97bb4", + "warmup_time": -1 + }, + "kernels.RBF.time_covfunc_call": { + "code": "class RBF:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RBF(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.RBF.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "b52f5ad2fdad31ce7060e8eb015e77504de6b2566db3b05e702d48e17f7c3e7f", + "warmup_time": -1 + }, + "kernels.RationalQuadratic.time_covfunc_call": { + "code": "class RationalQuadratic:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims)))", + "min_run_count": 2, + "name": "kernels.RationalQuadratic.time_covfunc_call", + "number": 0, + "param_names": [ + "n_data", + "dimensionality" + ], + "params": [ + [ + "10", + "100", + "500", + "1000", + "2000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "4ff62cadc9b2f84aa5f6ea06736910da029bd98f3f7191de57356b43d6915b42", + "warmup_time": -1 + }, + "linops.LinOps.time_inverse": { + "code": "class LinOps:\n def time_inverse(self, n_datapoints):\n self.linop.inverse()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", + "min_run_count": 2, + "name": "linops.LinOps.time_inverse", + "number": 0, + "param_names": [ + "n_data" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "823cf69fc1b04db01ca405df4e4ad858be5f2f961474f37024055ee6b184b59d", + "warmup_time": -1 + }, + "linops.LinOps.time_logdet": { + "code": "class LinOps:\n def time_logdet(self, n_datapoints):\n self.linop.log_det()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", + "min_run_count": 2, + "name": "linops.LinOps.time_logdet", + "number": 0, + "param_names": [ + "n_data" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "639dad2164ac90fc52cdc42feb86a3a123ad523816883172d84302c4b5b0cdb9", + "warmup_time": -1 + }, + "linops.LinOps.time_root": { + "code": "class LinOps:\n def time_root(self, n_datapoints):\n self.linop.to_root()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", + "min_run_count": 2, + "name": "linops.LinOps.time_root", + "number": 0, + "param_names": [ + "n_data" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "cae06127f9dd4abd0e43b5d56de47907b15a7914dec0001a3dc0bf8e6ede3443", + "warmup_time": -1 + }, + "linops.LinOps.time_solve": { + "code": "class LinOps:\n def time_solve(self, n_datapoints):\n self.linop.solve(self.y)\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", + "min_run_count": 2, + "name": "linops.LinOps.time_solve", + "number": 0, + "param_names": [ + "n_data" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "ae85c8782ac7af301f71850798f51a6e935da6685811c777f97ab715bbdb0ebc", + "warmup_time": -1 + }, + "objectives.Bernoulli.time_eval": { + "code": "class Bernoulli:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Bernoulli.time_eval", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "fb5ee5905aa83614349ecf957e77246930a4577b1b4308bb1fd4961104de464f", + "warmup_time": -1 + }, + "objectives.Bernoulli.time_grad": { + "code": "class Bernoulli:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Bernoulli.time_grad", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "38185efea870c669bb43effcdeb9736469e16211eb9bf1c385ef6e9e7016af9d", + "warmup_time": -1 + }, + "objectives.Gaussian.time_eval": { + "code": "class Gaussian:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Gaussian.time_eval", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "c95ff081d05fd04891867ccd92dd38fc091c1617f991faf7708322edd5763b26", + "warmup_time": -1 + }, + "objectives.Gaussian.time_grad": { + "code": "class Gaussian:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Gaussian.time_grad", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "17f8bbfec9594b825cce2619ff9cdff44460a0f3b9273276e132c466903cad5d", + "warmup_time": -1 + }, + "objectives.Poisson.time_eval": { + "code": "class Poisson:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Poisson(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Poisson.time_eval", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "c6980ed01dfd22897a43064bc3210aa38052a9a542e380652f67e7a93e575ce6", + "warmup_time": -1 + }, + "objectives.Poisson.time_grad": { + "code": "class Poisson:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Poisson(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", + "min_run_count": 2, + "name": "objectives.Poisson.time_grad", + "number": 0, + "param_names": [ + "n_data", + "n_dims" + ], + "params": [ + [ + "10", + "100", + "200", + "500", + "1000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "9da29fc2c40db47e799a629b998835c42f1188786ec4cb956931def49fe94db7", + "warmup_time": -1 + }, + "predictions.Bernoulli.time_predict": { + "code": "class Bernoulli:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", + "min_run_count": 2, + "name": "predictions.Bernoulli.time_predict", + "number": 0, + "param_names": [ + "n_test", + "n_dims" + ], + "params": [ + [ + "100", + "200", + "500", + "1000", + "2000", + "3000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "857bb8965761478deabc31a9c7d8c448e15b04040ad3000f3215ecfc25b6572a", + "warmup_time": -1 + }, + "predictions.Gaussian.time_predict": { + "code": "class Gaussian:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", + "min_run_count": 2, + "name": "predictions.Gaussian.time_predict", + "number": 0, + "param_names": [ + "n_test", + "n_dims" + ], + "params": [ + [ + "100", + "200", + "500", + "1000", + "2000", + "3000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "6f0e388859cf4b193a8b671902fd452e57ea9b7330f9a9226a3c683b9dd79fa1", + "warmup_time": -1 + }, + "predictions.Poisson.time_predict": { + "code": "class Poisson:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", + "min_run_count": 2, + "name": "predictions.Poisson.time_predict", + "number": 0, + "param_names": [ + "n_test", + "n_dims" + ], + "params": [ + [ + "100", + "200", + "500", + "1000", + "2000", + "3000" + ], + [ + "1", + "2", + "5" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "e551f6f771a828ecf51e53287b7c46c8df0944cdba11bf2b731272bbad6d0128", + "warmup_time": -1 + }, + "sparse.Sparse.time_eval": { + "code": "class Sparse:\n def time_eval(self, n_datapoints, n_dims):\n self.objective(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", + "min_run_count": 2, + "name": "sparse.Sparse.time_eval", + "number": 0, + "param_names": [ + "n_data", + "n_inducing" + ], + "params": [ + [ + "2000", + "5000", + "10000", + "20000" + ], + [ + "10", + "20", + "50", + "100", + "200" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "c42a0cef98e7ce98940fdd14075c567a03ab6e0217008f317c0b2ad4bc48bccb", + "warmup_time": -1 + }, + "sparse.Sparse.time_grad": { + "code": "class Sparse:\n def time_grad(self, n_datapoints, n_dims):\n jax.grad(self.objective)(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", + "min_run_count": 2, + "name": "sparse.Sparse.time_grad", + "number": 0, + "param_names": [ + "n_data", + "n_inducing" + ], + "params": [ + [ + "2000", + "5000", + "10000", + "20000" + ], + [ + "10", + "20", + "50", + "100", + "200" + ] + ], + "repeat": 0, + "rounds": 2, + "sample_time": 0.01, + "type": "time", + "unit": "seconds", + "version": "5aaf0153a37ed3daf24fa0e2a128884fc50602f21a8cc268d5ddb989aaabcd66", + "warmup_time": -1 + }, + "version": 2 +} \ No newline at end of file diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 528d966cb..0296edb4c 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -1,102 +1,20 @@ { "version": 1, - - // The name of the project being benchmarked "project": "gpjax", - - // The project's homepage "project_url": "https://jaxgaussianprocesses.com/", - - // The URL or local path of the source code repository for the - // project being benchmarked "repo": "..", - - // Customizable commands for building, installing, and - // uninstalling the project. See asv.conf.json documentation. "install_command": ["python -mpip install {wheel_file}"], - // "install_command": ["in-dir={env_dir} python {conf_dir}/benchmarks_install.py {commit} {env_dir} {build_dir}"], "build_command": [ "PIP_NO_BUILD_ISOLATION=false python -m pip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" ], - - // List of branches to benchmark. If not provided, defaults to "master" - // (for git) or "default" (for mercurial). - "branches": ["main"], // for git - // "branches": ["default"], // for mercurial - - // The DVCS being used. If not set, it will be automatically - // determined from "repo" by looking at the protocol in the URL - // (if remote), or by looking for special directories, such as - // ".git" (if local). + "branches": ["main", "benchmarking"], "dvcs": "git", - - // The tool to use to create environments. May be "conda", - // "virtualenv" or other value depending on the plugins in use. - // If missing or the empty string, the tool will be automatically - // determined by looking for tools on the PATH environment - // variable. "environment_type": "virtualenv", - - // timeout in seconds for installing any dependencies in environment - // defaults to 10 min - //"install_timeout": 600, - - // the base URL to show a commit for the project. "show_commit_url": "https://github.com/jaxgaussianprocesses/gpjax/commit/main", - - // The Pythons you'd like to test against. If not provided, defaults - // to the current version of Python used to run `asv`. "pythons": ["3.8"], - - // The list of conda channel names to be searched for benchmark - // dependency packages in the specified order - // "conda_channels": ["conda-forge", "defaults"], - - // The directory (relative to the current directory) that benchmarks are - // stored in. If not provided, defaults to "benchmarks" "benchmark_dir": ".", - - // The directory (relative to the current directory) to cache the Python - // environments in. If not provided, defaults to "env" "env_dir": ".asv/env", - - // The directory (relative to the current directory) that raw benchmark - // results are stored in. If not provided, defaults to "results". "results_dir": ".asv/results", - - // The directory (relative to the current directory) that the html tree - // should be written to. If not provided, defaults to "html". - "html_dir": "../docs/_build/html/benchmarks", - - // The number of characters to retain in the commit hashes. - // "hash_length": 8, - - // `asv` will cache results of the recent builds in each - // environment, making them faster to install next time. This is - // the number of builds to keep, per environment. - "build_cache_size": 2, - - // The commits after which the regression search in `asv publish` - // should start looking for regressions. Dictionary whose keys are - // regexps matching to benchmark names, and values corresponding to - // the commit (exclusive) after which to start looking for - // regressions. The default is to start from the first commit - // with results. If the commit is `null`, regression detection is - // skipped for the matching benchmark. - // - // "regressions_first_commits": { - // "some_benchmark": "352cdf", // Consider regressions only after this commit - // "another_benchmark": null, // Skip regression detection altogether - // }, - - // The thresholds for relative change in results, after which `asv - // publish` starts reporting regressions. Dictionary of the same - // form as in ``regressions_first_commits``, with values - // indicating the thresholds. If multiple entries match, the - // maximum is taken. If no entry matches, the default is 5%. - // - // "regressions_thresholds": { - // "some_benchmark": 0.01, // Threshold of 1% - // "another_benchmark": 0.5, // Threshold of 50% - // }, + "html_dir": ".asv/html", + "build_cache_size": 2 } diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py index 0323b65b8..a32129e6f 100644 --- a/benchmarks/kernels.py +++ b/benchmarks/kernels.py @@ -2,9 +2,10 @@ config.update("jax_enable_x64", True) -from gpjax import kernels import jax.random as jr +from gpjax import kernels + class Kernels: param_names = ["n_data", "dimensionality"] diff --git a/benchmarks/linops.py b/benchmarks/linops.py index 2b5def6a8..ab801273c 100644 --- a/benchmarks/linops.py +++ b/benchmarks/linops.py @@ -2,10 +2,11 @@ config.update("jax_enable_x64", True) -from gpjax.linops import DenseLinearOperator import jax.numpy as jnp -from sklearn.datasets import make_spd_matrix import jax.random as jr +from sklearn.datasets import make_spd_matrix + +from gpjax.linops import DenseLinearOperator class LinOps: diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py index 41adab175..830c36652 100644 --- a/benchmarks/objectives.py +++ b/benchmarks/objectives.py @@ -1,10 +1,11 @@ from jax.config import config config.update("jax_enable_x64", True) -import gpjax as gpx +import jax import jax.numpy as jnp import jax.random as jr -import jax + +import gpjax as gpx class Gaussian: diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index cfbc2ff55..644d20cbc 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -1,11 +1,15 @@ +from typing import TYPE_CHECKING + from jax.config import config config.update("jax_enable_x64", True) -import gpjax as gpx -from gpjax.gps import ConjugatePosterior import jax.numpy as jnp import jax.random as jr -import jax + +import gpjax as gpx + +if TYPE_CHECKING: + from gpjax.gps import ConjugatePosterior class Gaussian: diff --git a/benchmarks/sparse.py b/benchmarks/sparse.py index fbd8462f2..8d798c496 100644 --- a/benchmarks/sparse.py +++ b/benchmarks/sparse.py @@ -1,10 +1,11 @@ from jax.config import config config.update("jax_enable_x64", True) -import gpjax as gpx +import jax import jax.numpy as jnp import jax.random as jr -import jax + +import gpjax as gpx class Sparse: From 8058d00175379a62e4cb395d611a0fe753dc29ce Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Tue, 22 Aug 2023 22:29:13 +0200 Subject: [PATCH 22/76] Remove local results --- .../Toms-MacBook-Air-2.local/machine.json | 9 - .asv/results/benchmarks.json | 61 -- benchmarks/.asv/results/benchmarks.json | 728 ------------------ 3 files changed, 798 deletions(-) delete mode 100644 .asv/results/Toms-MacBook-Air-2.local/machine.json delete mode 100644 .asv/results/benchmarks.json delete mode 100644 benchmarks/.asv/results/benchmarks.json diff --git a/.asv/results/Toms-MacBook-Air-2.local/machine.json b/.asv/results/Toms-MacBook-Air-2.local/machine.json deleted file mode 100644 index 0222d4bdb..000000000 --- a/.asv/results/Toms-MacBook-Air-2.local/machine.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "arch": "arm64", - "cpu": "Apple M1", - "machine": "Toms-MacBook-Air-2.local", - "num_cpu": "8", - "os": "Darwin 22.3.0", - "ram": "8589934592", - "version": 1 -} \ No newline at end of file diff --git a/.asv/results/benchmarks.json b/.asv/results/benchmarks.json deleted file mode 100644 index 41974721f..000000000 --- a/.asv/results/benchmarks.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "kernels.MemSuite.mem_list": { - "code": "class MemSuite:\n def mem_list(self):\n return [0] * 256", - "name": "kernels.MemSuite.mem_list", - "param_names": [], - "params": [], - "timeout": 60.0, - "type": "memory", - "unit": "bytes", - "version": "abe86bab484550a681c61d7bb6eb081fbd37eb6d5009eba1df85c935530577b9" - }, - "kernels.TimeSuite.time_keys": { - "code": "class TimeSuite:\n def time_keys(self):\n for key in self.d.keys():\n pass\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", - "min_run_count": 2, - "name": "kernels.TimeSuite.time_keys", - "number": 0, - "param_names": [], - "params": [], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "86e015a3c40c52da31e4185fff7c7176c38c5e1e1e4aba71912db0b388225191", - "warmup_time": -1 - }, - "kernels.TimeSuite.time_range": { - "code": "class TimeSuite:\n def time_range(self):\n d = self.d\n for key in range(500):\n x = d[key]\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", - "min_run_count": 2, - "name": "kernels.TimeSuite.time_range", - "number": 0, - "param_names": [], - "params": [], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "cc3e85248a6284df968bcf8afe866da285261eb2487c10e9dd9e2d17a05deb47", - "warmup_time": -1 - }, - "kernels.TimeSuite.time_values": { - "code": "class TimeSuite:\n def time_values(self):\n for value in self.d.values():\n pass\n\n def setup(self):\n self.d = {}\n for x in range(500):\n self.d[x] = None", - "min_run_count": 2, - "name": "kernels.TimeSuite.time_values", - "number": 0, - "param_names": [], - "params": [], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "timeout": 60.0, - "type": "time", - "unit": "seconds", - "version": "cace9f2d006aa364dcf5762823afba3680c2fb50179ee30beaf880c0697256e2", - "warmup_time": -1 - }, - "version": 2 -} \ No newline at end of file diff --git a/benchmarks/.asv/results/benchmarks.json b/benchmarks/.asv/results/benchmarks.json deleted file mode 100644 index fd6f2304e..000000000 --- a/benchmarks/.asv/results/benchmarks.json +++ /dev/null @@ -1,728 +0,0 @@ -{ - "kernels.ArcCosine.time_covfunc_call": { - "code": "class ArcCosine:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.ArcCosine.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "f923a5feb1913469c66f702d89993918b418cc376b993df1cb7b974c3af01dfe", - "warmup_time": -1 - }, - "kernels.Linear.time_covfunc_call": { - "code": "class Linear:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Linear(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Linear.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "937688fe2a0aa44886c8c5856202502b9c82d2043d1034bf1c5984d73999b6b3", - "warmup_time": -1 - }, - "kernels.Matern12.time_covfunc_call": { - "code": "class Matern12:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern12(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern12.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "847a1c25403643211b2dbe93ac755ad2ddcd5da5e2b53136841d6ab99cc12699", - "warmup_time": -1 - }, - "kernels.Matern32.time_covfunc_call": { - "code": "class Matern32:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern32(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern32.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "a520e46707f3b3181f63c1e1a372e9e6cea4d8bcfc1d24ab4b7f40ff1dadf171", - "warmup_time": -1 - }, - "kernels.Matern52.time_covfunc_call": { - "code": "class Matern52:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Matern52(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Matern52.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "179838852e999abcac68e90c141724342d0b4a25656f5ea7be6409ac9205b91f", - "warmup_time": -1 - }, - "kernels.Polynomial.time_covfunc_call": { - "code": "class Polynomial:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.Polynomial(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.Polynomial.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "67213fe983f9f09d6213609250aab0870f9b652c1fb08e07f68581af193365d5", - "warmup_time": -1 - }, - "kernels.PoweredExponential.time_covfunc_call": { - "code": "class PoweredExponential:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.PoweredExponential.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "2da6e3291d5e431eed969aaba40c4b42f226ebad022e3ea56b257ab2e2e97bb4", - "warmup_time": -1 - }, - "kernels.RBF.time_covfunc_call": { - "code": "class RBF:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RBF(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.RBF.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "b52f5ad2fdad31ce7060e8eb015e77504de6b2566db3b05e702d48e17f7c3e7f", - "warmup_time": -1 - }, - "kernels.RationalQuadratic.time_covfunc_call": { - "code": "class RationalQuadratic:\n def time_covfunc_call(self, n_datapoints, n_dims):\n self.kernel.gram(self.X)\n\n def setup(self, n_datapoints, n_dims):\n super().setup(n_datapoints, n_dims)\n self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims)))", - "min_run_count": 2, - "name": "kernels.RationalQuadratic.time_covfunc_call", - "number": 0, - "param_names": [ - "n_data", - "dimensionality" - ], - "params": [ - [ - "10", - "100", - "500", - "1000", - "2000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "4ff62cadc9b2f84aa5f6ea06736910da029bd98f3f7191de57356b43d6915b42", - "warmup_time": -1 - }, - "linops.LinOps.time_inverse": { - "code": "class LinOps:\n def time_inverse(self, n_datapoints):\n self.linop.inverse()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", - "min_run_count": 2, - "name": "linops.LinOps.time_inverse", - "number": 0, - "param_names": [ - "n_data" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "823cf69fc1b04db01ca405df4e4ad858be5f2f961474f37024055ee6b184b59d", - "warmup_time": -1 - }, - "linops.LinOps.time_logdet": { - "code": "class LinOps:\n def time_logdet(self, n_datapoints):\n self.linop.log_det()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", - "min_run_count": 2, - "name": "linops.LinOps.time_logdet", - "number": 0, - "param_names": [ - "n_data" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "639dad2164ac90fc52cdc42feb86a3a123ad523816883172d84302c4b5b0cdb9", - "warmup_time": -1 - }, - "linops.LinOps.time_root": { - "code": "class LinOps:\n def time_root(self, n_datapoints):\n self.linop.to_root()\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", - "min_run_count": 2, - "name": "linops.LinOps.time_root", - "number": 0, - "param_names": [ - "n_data" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "cae06127f9dd4abd0e43b5d56de47907b15a7914dec0001a3dc0bf8e6ede3443", - "warmup_time": -1 - }, - "linops.LinOps.time_solve": { - "code": "class LinOps:\n def time_solve(self, n_datapoints):\n self.linop.solve(self.y)\n\n def setup(self, n_datapoints):\n key = jr.PRNGKey(123)\n self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123))\n self.y = jr.normal(key=key, shape=(n_datapoints, 1))\n self.linop = DenseLinearOperator(matrix=self.X)", - "min_run_count": 2, - "name": "linops.LinOps.time_solve", - "number": 0, - "param_names": [ - "n_data" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "ae85c8782ac7af301f71850798f51a6e935da6685811c777f97ab715bbdb0ebc", - "warmup_time": -1 - }, - "objectives.Bernoulli.time_eval": { - "code": "class Bernoulli:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Bernoulli.time_eval", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "fb5ee5905aa83614349ecf957e77246930a4577b1b4308bb1fd4961104de464f", - "warmup_time": -1 - }, - "objectives.Bernoulli.time_grad": { - "code": "class Bernoulli:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Bernoulli.time_grad", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "38185efea870c669bb43effcdeb9736469e16211eb9bf1c385ef6e9e7016af9d", - "warmup_time": -1 - }, - "objectives.Gaussian.time_eval": { - "code": "class Gaussian:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Gaussian.time_eval", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "c95ff081d05fd04891867ccd92dd38fc091c1617f991faf7708322edd5763b26", - "warmup_time": -1 - }, - "objectives.Gaussian.time_grad": { - "code": "class Gaussian:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.objective = gpx.ConjugateMLL()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Gaussian.time_grad", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "17f8bbfec9594b825cce2619ff9cdff44460a0f3b9273276e132c466903cad5d", - "warmup_time": -1 - }, - "objectives.Poisson.time_eval": { - "code": "class Poisson:\n def time_eval(self, n_datapoints, n_dims):\n self.objective.step(self.posterior, self.data).block_until_ready()\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Poisson(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Poisson.time_eval", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "c6980ed01dfd22897a43064bc3210aa38052a9a542e380652f67e7a93e575ce6", - "warmup_time": -1 - }, - "objectives.Poisson.time_grad": { - "code": "class Poisson:\n def time_grad(self, n_datapoints, n_dims):\n jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data))\n\n def setup(self, n_datapoints, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Poisson(num_datapoints=self.data.n)\n self.objective = gpx.LogPosteriorDensity()\n self.posterior = self.prior * self.likelihood", - "min_run_count": 2, - "name": "objectives.Poisson.time_grad", - "number": 0, - "param_names": [ - "n_data", - "n_dims" - ], - "params": [ - [ - "10", - "100", - "200", - "500", - "1000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "9da29fc2c40db47e799a629b998835c42f1188786ec4cb956931def49fe94db7", - "warmup_time": -1 - }, - "predictions.Bernoulli.time_predict": { - "code": "class Bernoulli:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.y = jnp.where(self.y > 0, 1, 0)\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", - "min_run_count": 2, - "name": "predictions.Bernoulli.time_predict", - "number": 0, - "param_names": [ - "n_test", - "n_dims" - ], - "params": [ - [ - "100", - "200", - "500", - "1000", - "2000", - "3000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "857bb8965761478deabc31a9c7d8c448e15b04040ad3000f3215ecfc25b6572a", - "warmup_time": -1 - }, - "predictions.Gaussian.time_predict": { - "code": "class Gaussian:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", - "min_run_count": 2, - "name": "predictions.Gaussian.time_predict", - "number": 0, - "param_names": [ - "n_test", - "n_dims" - ], - "params": [ - [ - "100", - "200", - "500", - "1000", - "2000", - "3000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "6f0e388859cf4b193a8b671902fd452e57ea9b7330f9a9226a3c683b9dd79fa1", - "warmup_time": -1 - }, - "predictions.Poisson.time_predict": { - "code": "class Poisson:\n def time_predict(self, n_test, n_dims):\n self.posterior.predict(test_inputs=self.xtest, train_data=self.data)\n\n def setup(self, n_test, n_dims):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(100, n_dims))\n f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function\n self.y = jr.poisson(key, jnp.exp(f(self.X)))\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(n_dims)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n)\n self.posterior: ConjugatePosterior = self.prior * self.likelihood\n key, subkey = jr.split(key)\n self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims))", - "min_run_count": 2, - "name": "predictions.Poisson.time_predict", - "number": 0, - "param_names": [ - "n_test", - "n_dims" - ], - "params": [ - [ - "100", - "200", - "500", - "1000", - "2000", - "3000" - ], - [ - "1", - "2", - "5" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "e551f6f771a828ecf51e53287b7c46c8df0944cdba11bf2b731272bbad6d0128", - "warmup_time": -1 - }, - "sparse.Sparse.time_eval": { - "code": "class Sparse:\n def time_eval(self, n_datapoints, n_dims):\n self.objective(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", - "min_run_count": 2, - "name": "sparse.Sparse.time_eval", - "number": 0, - "param_names": [ - "n_data", - "n_inducing" - ], - "params": [ - [ - "2000", - "5000", - "10000", - "20000" - ], - [ - "10", - "20", - "50", - "100", - "200" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "c42a0cef98e7ce98940fdd14075c567a03ab6e0217008f317c0b2ad4bc48bccb", - "warmup_time": -1 - }, - "sparse.Sparse.time_grad": { - "code": "class Sparse:\n def time_grad(self, n_datapoints, n_dims):\n jax.grad(self.objective)(self.q, self.data)\n\n def setup(self, n_datapoints, n_inducing):\n key = jr.PRNGKey(123)\n self.X = jr.normal(key=key, shape=(n_datapoints, 1))\n self.y = jnp.sin(self.X[:, :1])\n self.data = gpx.Dataset(X=self.X, y=self.y)\n kernel = gpx.kernels.RBF(active_dims=list(range(1)))\n meanf = gpx.mean_functions.Constant()\n self.prior = gpx.Prior(kernel=kernel, mean_function=meanf)\n self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n)\n self.posterior = self.prior * self.likelihood\n \n Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1)\n self.q = gpx.CollapsedVariationalGaussian(\n posterior=self.posterior, inducing_inputs=Z\n )\n self.objective = gpx.CollapsedELBO(negative=True)", - "min_run_count": 2, - "name": "sparse.Sparse.time_grad", - "number": 0, - "param_names": [ - "n_data", - "n_inducing" - ], - "params": [ - [ - "2000", - "5000", - "10000", - "20000" - ], - [ - "10", - "20", - "50", - "100", - "200" - ] - ], - "repeat": 0, - "rounds": 2, - "sample_time": 0.01, - "type": "time", - "unit": "seconds", - "version": "5aaf0153a37ed3daf24fa0e2a128884fc50602f21a8cc268d5ddb989aaabcd66", - "warmup_time": -1 - }, - "version": 2 -} \ No newline at end of file From eb4a11c3bd975bc0530ba93b2226dbd0e6f53a82 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Wed, 23 Aug 2023 08:30:46 +0200 Subject: [PATCH 23/76] Ensure float64 --- benchmarks/predictions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index 644d20cbc..f66133ec0 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -47,7 +47,7 @@ def setup(self, n_test, n_dims): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) self.y = jnp.sin(self.X[:, :1]) - self.y = jnp.where(self.y > 0, 1, 0) + self.y = jnp.array(jnp.where(self.y > 0, 1, 0), dtype=jnp.float64) self.data = gpx.Dataset(X=self.X, y=self.y) kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) meanf = gpx.mean_functions.Constant() @@ -72,7 +72,7 @@ def setup(self, n_test, n_dims): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function - self.y = jr.poisson(key, jnp.exp(f(self.X))) + self.y = jnp.array(jr.poisson(key, jnp.exp(f(self.X))), dtype=jnp.float64) self.data = gpx.Dataset(X=self.X, y=self.y) kernel = gpx.kernels.RBF(active_dims=list(range(n_dims))) meanf = gpx.mean_functions.Constant() From ab2b94c7644d7870b5de98e085224ce6756c22b5 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Wed, 23 Aug 2023 08:31:07 +0200 Subject: [PATCH 24/76] Drop dynamic versioning --- gpjax/__init__.py | 2 +- pyproject.toml | 65 +++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/gpjax/__init__.py b/gpjax/__init__.py index 4954e526d..efcce652f 100644 --- a/gpjax/__init__.py +++ b/gpjax/__init__.py @@ -75,7 +75,7 @@ __description__ = "Didactic Gaussian processes in JAX" __url__ = "https://github.com/JaxGaussianProcesses/GPJax" __contributors__ = "https://github.com/JaxGaussianProcesses/GPJax/graphs/contributors" -__version__ = "0.0.0" +__version__ = "0.6.8" __all__ = [ "Module", diff --git a/pyproject.toml b/pyproject.toml index 29a0d976c..98613caf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,18 +1,19 @@ [tool.poetry] name = "gpjax" -version = "0.0.0" # Merely a placeholder, will be replaced by the dynamic versioning plugin +version = "0.6.8" description = "Gaussian processes in JAX." -authors = ["Thomas Pinder ", "Daniel Dodd "] +authors = [ + "Thomas Pinder ", + "Daniel Dodd ", +] license = "Apache-2.0" readme = "README.md" homepage = "https://github.com/JaxGaussianProcesses/GPJax" repository = "https://github.com/JaxGaussianProcesses/GPJax" -include = [ - "LICENSE", -] +include = ["LICENSE"] documentation = "https://docs.jaxgaussianprocesses.com/" keywords = ["gaussian-processes jax machine-learning bayesian"] -packages = [{include = "gpjax"}] +packages = [{ include = "gpjax" }] [tool.poetry.dependencies] python = ">=3.8,<3.12" @@ -24,7 +25,7 @@ simple-pytree = "^0.1.7" tensorflow-probability = "^0.19.0" orbax-checkpoint = "^0.2.0" beartype = "^0.13.1" -jaxlib = "0.4.7" # Temporary fix: https://github.com/google/jax/issues/15951 +jaxlib = "0.4.7" # Temporary fix: https://github.com/google/jax/issues/15951 plum-dispatch = "^2.1.0" [tool.poetry.group.test.dependencies] @@ -88,24 +89,24 @@ pytkdocs = "^0.16.1" mkdocs-gen-files = "^0.5.0" mkdocs-literate-nav = "^0.6.0" mkdocs-git-authors-plugin = "^0.7.0" -mkdocstrings = {version = "^0.21.2", extras = ["python"]} +mkdocstrings = { version = "^0.21.2", extras = ["python"] } markdown-katex = "^202112.1034" [build-system] -requires = ["poetry-core", "poetry-dynamic-versioning"] -build-backend = "poetry_dynamic_versioning.backend" +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" -[tool.black] # https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file +[tool.black] # https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file line-length = 88 target-version = ["py38"] -[tool.pytest.ini_options] # https://docs.pytest.org/en/latest/reference/reference.html#ini-options-ref +[tool.pytest.ini_options] # https://docs.pytest.org/en/latest/reference/reference.html#ini-options-ref # addopts = "--color=yes --doctest-modules --exitfirst --failed-first --strict-config --strict-markers --typeguard-packages=my_package --verbosity=2 --junitxml=reports/pytest.xml" filterwarnings = ["error", "ignore::DeprecationWarning"] testpaths = ["gpjax", "tests"] xfail_strict = true -[tool.ruff] # https://github.com/charliermarsh/ruff +[tool.ruff] # https://github.com/charliermarsh/ruff fix = true cache-dir = "~/.cache/ruff" dummy-variable-rgx = "^_$" @@ -125,7 +126,9 @@ select = [ # flake8-quotes "Q", # pylint - "PLE", "PLR", "PLW", + "PLE", + "PLR", + "PLW", # misc lints "PIE", # flake8-pyi @@ -138,20 +141,20 @@ select = [ "TCH", ] ignore = [ - # space before : (needed for how black formats slicing) - # "E203", # not yet implemented - # module level import not at top of file - "E402", - # do not assign a lambda expression, use a def - "E731", - "E501", - "PGH001", - "RET504", - "S101", - "F722", - 'PLR2004', - "PLR0913" - ] + # space before : (needed for how black formats slicing) + # "E203", # not yet implemented + # module level import not at top of file + "E402", + # do not assign a lambda expression, use a def + "E731", + "E501", + "PGH001", + "RET504", + "S101", + "F722", + 'PLR2004', + "PLR0913", +] unfixable = ["ERA001", "F401", "F841", "T201", "T203"] src = ["gpjax", "tests"] target-version = "py38" @@ -177,19 +180,19 @@ force_sort_within_sections = true force_grid_wrap = 2 skip = 'docs' -[tool.coverage.report] # https://coverage.readthedocs.io/en/latest/config.html#report +[tool.coverage.report] # https://coverage.readthedocs.io/en/latest/config.html#report fail_under = 50 precision = 1 show_missing = true skip_covered = true -[tool.coverage.run] # https://coverage.readthedocs.io/en/latest/config.html#run +[tool.coverage.run] # https://coverage.readthedocs.io/en/latest/config.html#run branch = true command_line = "--module pytest" data_file = "reports/.coverage" source = ["src"] -[tool.coverage.xml] # https://coverage.readthedocs.io/en/latest/config.html#xml +[tool.coverage.xml] # https://coverage.readthedocs.io/en/latest/config.html#xml output = "reports/coverage.xml" [tool.poetry-dynamic-versioning] From c4e473908d2067076cb2635972567e0463cfbd7f Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Wed, 23 Aug 2023 09:02:03 +0200 Subject: [PATCH 25/76] Update config --- benchmarks/asv.conf.json | 2 +- poetry.lock | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 0296edb4c..1d4353b13 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -7,7 +7,7 @@ "build_command": [ "PIP_NO_BUILD_ISOLATION=false python -m pip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" ], - "branches": ["main", "benchmarking"], + "branches": ["main"], "dvcs": "git", "environment_type": "virtualenv", "show_commit_url": "https://github.com/jaxgaussianprocesses/gpjax/commit/main", diff --git a/poetry.lock b/poetry.lock index d22fbc538..ba4e5dff4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2986,8 +2986,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.8,<3.12" -content-hash = "7e057e35bc4438a123be1a7479ae6383b1ae10129ba6b94690b0ee001137aa10" - +content-hash = "243077f4ff98c3b2ab5bdd33795c3dd191ff248142199b3d73ad2f819da14628" [metadata.files] absl-py = [ From fd59f0fa266219d20222ce215b88747e2fe4cfa2 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Thu, 24 Aug 2023 06:23:31 +0200 Subject: [PATCH 26/76] Respond to review --- benchmarks/kernels.py | 2 +- benchmarks/linops.py | 2 +- benchmarks/objectives.py | 2 +- benchmarks/predictions.py | 8 ++++---- benchmarks/sparse.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py index a32129e6f..a1074581d 100644 --- a/benchmarks/kernels.py +++ b/benchmarks/kernels.py @@ -1,4 +1,4 @@ -from jax.config import config +from jax import config config.update("jax_enable_x64", True) diff --git a/benchmarks/linops.py b/benchmarks/linops.py index ab801273c..3772ec289 100644 --- a/benchmarks/linops.py +++ b/benchmarks/linops.py @@ -1,4 +1,4 @@ -from jax.config import config +from jax import config config.update("jax_enable_x64", True) diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py index 830c36652..077269191 100644 --- a/benchmarks/objectives.py +++ b/benchmarks/objectives.py @@ -1,4 +1,4 @@ -from jax.config import config +from jax import config config.update("jax_enable_x64", True) import jax diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index f66133ec0..c533cb3ee 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from jax.config import config +from jax import config config.update("jax_enable_x64", True) import jax.numpy as jnp @@ -28,7 +28,7 @@ def setup(self, n_test, n_dims): meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) - self.posterior: ConjugatePosterior = self.prior * self.likelihood + self.posterior = self.prior * self.likelihood key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) @@ -53,7 +53,7 @@ def setup(self, n_test, n_dims): meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) - self.posterior: ConjugatePosterior = self.prior * self.likelihood + self.posterior = self.prior * self.likelihood key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) @@ -78,7 +78,7 @@ def setup(self, n_test, n_dims): meanf = gpx.mean_functions.Constant() self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) self.likelihood = gpx.likelihoods.Bernoulli(num_datapoints=self.data.n) - self.posterior: ConjugatePosterior = self.prior * self.likelihood + self.posterior = self.prior * self.likelihood key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) diff --git a/benchmarks/sparse.py b/benchmarks/sparse.py index 8d798c496..2758b365f 100644 --- a/benchmarks/sparse.py +++ b/benchmarks/sparse.py @@ -1,4 +1,4 @@ -from jax.config import config +from jax import config config.update("jax_enable_x64", True) import jax From 26a7109368374dcbd52b1f8b218c052a235e88a3 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Thu, 24 Aug 2023 06:25:02 +0200 Subject: [PATCH 27/76] Fix imports --- benchmarks/predictions.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index c533cb3ee..19aa44171 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -1,5 +1,3 @@ -from typing import TYPE_CHECKING - from jax import config config.update("jax_enable_x64", True) @@ -8,9 +6,6 @@ import gpjax as gpx -if TYPE_CHECKING: - from gpjax.gps import ConjugatePosterior - class Gaussian: param_names = [ From 450a2777f0f56b0165175b386152a20f306cf1ce Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Thu, 24 Aug 2023 14:39:28 +0100 Subject: [PATCH 28/76] completed vector fields/ocean modelling notebook --- docs/examples/data/UV_test_vortex.csv | 289 ------------- docs/examples/data/UV_train_vortex.csv | 8 - docs/examples/data/XY_test_vortex.csv | 289 ------------- docs/examples/data/XY_train_vortex.csv | 8 - docs/examples/data/gulfdata_test.csv | 545 +++++++++++++++++++++++++ docs/examples/data/gulfdata_train.csv | 21 + docs/examples/oceanmodelling.py | 477 ++++++++++++++++++++++ docs/examples/vectorfields.py | 493 ---------------------- 8 files changed, 1043 insertions(+), 1087 deletions(-) delete mode 100644 docs/examples/data/UV_test_vortex.csv delete mode 100644 docs/examples/data/UV_train_vortex.csv delete mode 100644 docs/examples/data/XY_test_vortex.csv delete mode 100644 docs/examples/data/XY_train_vortex.csv create mode 100644 docs/examples/data/gulfdata_test.csv create mode 100644 docs/examples/data/gulfdata_train.csv create mode 100644 docs/examples/oceanmodelling.py delete mode 100644 docs/examples/vectorfields.py diff --git a/docs/examples/data/UV_test_vortex.csv b/docs/examples/data/UV_test_vortex.csv deleted file mode 100644 index 35abb06e5..000000000 --- a/docs/examples/data/UV_test_vortex.csv +++ /dev/null @@ -1,289 +0,0 @@ -1.004967093467712402e+00,-1.006227016448974609e+00 -9.986173510551452637e-01,-8.796322345733642578e-01 -1.006476879119873047e+00,-7.600320577621459961e-01 -1.015230298042297363e+00,-6.385467052459716797e-01 -9.976584911346435547e-01,-5.017080903053283691e-01 -9.976586103439331055e-01,-3.841849565505981445e-01 -1.015792131423950195e+00,-2.722352147102355957e-01 -1.007674336433410645e+00,-1.338611394166946411e-01 -9.953052401542663574e-01,-1.733516715466976166e-02 -1.005425572395324707e+00,1.101694405078887939e-01 -9.953657984733581543e-01,2.307860851287841797e-01 -9.953427314758300781e-01,3.386488258838653564e-01 -1.002419590950012207e+00,4.637859463691711426e-01 -9.808672070503234863e-01,5.993096828460693359e-01 -9.827508330345153809e-01,7.203894257545471191e-01 -9.943771362304687500e-01,8.365256786346435547e-01 -9.898716807365417480e-01,9.603569507598876953e-01 -8.806934952735900879e-01,-9.872233271598815918e-01 -8.684707880020141602e-01,-8.834667205810546875e-01 -8.634279966354370117e-01,-7.496310472488403320e-01 -8.922075033187866211e-01,-6.346749663352966309e-01 -8.752932548522949219e-01,-5.123808979988098145e-01 -8.782262802124023438e-01,-3.767673373222351074e-01 -8.633035421371459961e-01,-2.570519447326660156e-01 -8.721072077751159668e-01,-1.347220391035079956e-01 -8.786602616310119629e-01,-7.353375200182199478e-03 -8.660410642623901367e-01,1.022508516907691956e-01 -8.813080191612243652e-01,2.313093245029449463e-01 -8.715446591377258301e-01,3.438360989093780518e-01 -8.746340870857238770e-01,4.726294279098510742e-01 -8.715339303016662598e-01,5.905352830886840820e-01 -8.960738182067871094e-01,7.152556777000427246e-01 -8.774160742759704590e-01,8.426862359046936035e-01 -8.669739365577697754e-01,9.510014653205871582e-01 -7.633274793624877930e-01,-9.790761470794677734e-01 -7.428935766220092773e-01,-8.876112103462219238e-01 -7.571907043457031250e-01,-7.672439217567443848e-01 -7.355053424835205078e-01,-6.210719347000122070e-01 -7.418201565742492676e-01,-5.022874474525451660e-01 -7.570706605911254883e-01,-3.815138936042785645e-01 -7.624866962432861328e-01,-2.590226531028747559e-01 -7.568157315254211426e-01,-1.429796069860458374e-01 -7.539455294609069824e-01,-2.938070707023143768e-02 -7.520909905433654785e-01,1.027988642454147339e-01 -7.403168082237243652e-01,2.177181839942932129e-01 -7.479035854339599609e-01,3.566899597644805908e-01 -7.504956722259521484e-01,4.679171741008758545e-01 -7.656732797622680664e-01,5.835817456245422363e-01 -7.585382461547851562e-01,7.110718488693237305e-01 -7.374716401100158691e-01,8.408640027046203613e-01 -7.583428621292114258e-01,9.535464048385620117e-01 -6.288022398948669434e-01,-1.008222222328186035e+00 -6.258838176727294922e-01,-8.751141428947448730e-01 -6.387698054313659668e-01,-7.526523470878601074e-01 -6.429630517959594727e-01,-6.377224922180175781e-01 -6.419658660888671875e-01,-5.149144530296325684e-01 -6.242609024047851562e-01,-3.854345977306365967e-01 -6.295609474182128906e-01,-2.797869741916656494e-01 -6.359657049179077148e-01,-1.569317877292633057e-01 -6.424084901809692383e-01,-2.759260497987270355e-02 -6.278613209724426270e-01,9.990634769201278687e-02 -6.307964920997619629e-01,2.275988757610321045e-01 -6.215897202491760254e-01,3.616923391819000244e-01 -6.206910014152526855e-01,4.779643416404724121e-01 -6.407783031463623047e-01,5.902373790740966797e-01 -6.462154388427734375e-01,7.140955328941345215e-01 -6.319329738616943359e-01,8.267093896865844727e-01 -6.426883935928344727e-01,9.589985609054565430e-01 -5.138204693794250488e-01,-1.002886533737182617e+00 -5.037528872489929199e-01,-8.743238449096679688e-01 -5.138180255889892578e-01,-7.633743286132812500e-01 -5.255844593048095703e-01,-6.274595856666564941e-01 -5.098457932472229004e-01,-4.948766827583312988e-01 -5.258505344390869141e-01,-3.888427019119262695e-01 -4.840066432952880859e-01,-2.612890005111694336e-01 -5.184230804443359375e-01,-1.359557062387466431e-01 -5.110745429992675781e-01,-2.442036755383014679e-02 -5.072140097618103027e-01,1.042817384004592896e-01 -5.111216902732849121e-01,2.246157228946685791e-01 -4.903284013271331787e-01,3.479155302047729492e-01 -5.080073475837707520e-01,4.616576433181762695e-01 -5.137752294540405273e-01,5.920818448066711426e-01 -5.249830484390258789e-01,7.192656993865966797e-01 -5.050213932991027832e-01,8.512461185455322266e-01 -5.021191239356994629e-01,9.687764048576354980e-01 -3.827375173568725586e-01,-9.784681797027587891e-01 -3.969091176986694336e-01,-8.852245211601257324e-01 -3.910426199436187744e-01,-7.463788390159606934e-01 -3.824574947357177734e-01,-6.308196187019348145e-01 -3.928877711296081543e-01,-4.883060455322265625e-01 -3.887258768081665039e-01,-3.958380818367004395e-01 -3.974415659904479980e-01,-2.737033367156982422e-01 -3.807345628738403320e-01,-1.488510668277740479e-01 -3.844784796237945557e-01,-4.164712131023406982e-02 -3.838340342044830322e-01,9.678326547145843506e-02 -3.731199502944946289e-01,2.168984711170196533e-01 -3.907163143157958984e-01,3.484427034854888916e-01 -3.903656601905822754e-01,4.728053212165832520e-01 -3.878062367439270020e-01,6.105984449386596680e-01 -3.854092359542846680e-01,7.237899303436279297e-01 -3.736014068126678467e-01,8.309656381607055664e-01 -3.835486471652984619e-01,9.501995444297790527e-01 -2.618789672851562500e-01,-9.950808286666870117e-01 -2.572833597660064697e-01,-8.907533288002014160e-01 -2.636932730674743652e-01,-7.367874383926391602e-01 -2.693466246128082275e-01,-6.208586692810058594e-01 -2.841679751873016357e-01,-5.148958563804626465e-01 -2.670519053936004639e-01,-4.048864543437957764e-01 -2.678816318511962891e-01,-2.517673969268798828e-01 -2.645616531372070312e-01,-1.440025418996810913e-01 -2.461184114217758179e-01,-8.030000142753124237e-03 -2.650409936904907227e-01,8.609654009342193604e-02 -2.659084200859069824e-01,2.184960395097732544e-01 -2.899385392665863037e-01,3.469912111759185791e-01 -2.633825242519378662e-01,4.698575735092163086e-01 -2.683216035366058350e-01,5.873360633850097656e-01 -2.649590075016021729e-01,7.205142378807067871e-01 -2.536193430423736572e-01,8.260585069656372070e-01 -2.767343521118164062e-01,9.577598571777343750e-01 -1.503764688968658447e-01,-9.987970590591430664e-01 -1.507674604654312134e-01,-8.724066615104675293e-01 -1.337632685899734497e-01,-7.479858994483947754e-01 -1.568850874900817871e-01,-6.438995003700256348e-01 -1.288386285305023193e-01,-5.255452394485473633e-01 -1.487257182598114014e-01,-3.749783337116241455e-01 -1.647616922855377197e-01,-2.619829773902893066e-01 -1.329517811536788940e-01,-1.503420025110244751e-01 -1.371941715478897095e-01,-4.896643571555614471e-03 -1.438536494970321655e-01,1.031975597143173218e-01 -1.378223896026611328e-01,2.362827658653259277e-01 -1.273505091667175293e-01,3.476139605045318604e-01 -1.435427665710449219e-01,4.899952411651611328e-01 -1.322341114282608032e-01,6.093901395797729492e-01 -1.475930660963058472e-01,7.117960453033447266e-01 -1.336628943681716919e-01,8.464503884315490723e-01 -1.583564877510070801e-01,9.656374454498291016e-01 -1.257563009858131409e-02,-9.863137006759643555e-01 -1.718754880130290985e-02,-8.872002363204956055e-01 -2.854333631694316864e-02,-7.482415437698364258e-01 -8.099519647657871246e-03,-6.220688223838806152e-01 -2.268276177346706390e-02,-5.277915000915527344e-01 -3.347958996891975403e-02,-3.995876908302307129e-01 -4.333330783993005753e-03,-2.856984436511993408e-01 -2.225450240075588226e-02,-1.455512046813964844e-01 -2.300699055194854736e-02,-1.323274057358503342e-02 -2.822639234364032745e-02,1.170643866062164307e-01 -8.038655854761600494e-03,2.252307385206222534e-01 -7.203597109764814377e-03,3.632249236106872559e-01 -2.562757954001426697e-02,4.555867314338684082e-01 -2.337801083922386169e-02,5.748029351234436035e-01 -2.291309088468551636e-02,7.137302160263061523e-01 -2.387264557182788849e-02,8.405753374099731445e-01 -1.360791642218828201e-02,9.588567018508911133e-01 --9.971828013658523560e-02,-1.020674467086791992e+00 --9.911008924245834351e-02,-8.784422278404235840e-01 --1.091843321919441223e-01,-7.681467533111572266e-01 --8.338306844234466553e-02,-6.259563565254211426e-01 --9.730248898267745972e-02,-5.065380930900573730e-01 --1.139538511633872986e-01,-3.971539139747619629e-01 --9.547527879476547241e-02,-2.704447805881500244e-01 --1.117876321077346802e-01,-1.534492820501327515e-01 --9.416996687650680542e-02,-2.103495411574840546e-02 --9.045486152172088623e-02,1.115922406315803528e-01 --1.102476418018341064e-01,2.146325409412384033e-01 --9.240705519914627075e-02,3.519792258739471436e-01 --9.791300445795059204e-02,4.640851914882659912e-01 --9.382021427154541016e-02,5.839080214500427246e-01 --8.307288587093353271e-02,7.132154107093811035e-01 --1.044946983456611633e-01,8.263822793960571289e-01 --1.095781773328781128e-01,9.536471962928771973e-01 --2.333849370479583740e-01,-1.011978745460510254e+00 --2.326478958129882812e-01,-8.579037785530090332e-01 --2.252608090639114380e-01,-7.547494173049926758e-01 --2.210782766342163086e-01,-6.396503448486328125e-01 --2.217228859663009644e-01,-5.080642700195312500e-01 --2.162179648876190186e-01,-3.888783752918243408e-01 --2.243597805500030518e-01,-2.675158083438873291e-01 --2.099544554948806763e-01,-1.367154717445373535e-01 --2.271363586187362671e-01,-1.283308584243059158e-02 --1.972881108522415161e-01,9.673580527305603027e-02 --2.182331234216690063e-01,2.187316119670867920e-01 --2.330613732337951660e-01,3.441882729530334473e-01 --2.351987212896347046e-01,4.463685452938079834e-01 --2.196650654077529907e-01,5.766848325729370117e-01 --2.267244309186935425e-01,7.279544472694396973e-01 --2.173497974872589111e-01,8.531843423843383789e-01 --2.197574228048324585e-01,9.566932916641235352e-01 --3.476670682430267334e-01,-9.942344427108764648e-01 --3.554067015647888184e-01,-8.744385242462158203e-01 --3.620872497558593750e-01,-7.243132591247558594e-01 --3.514039218425750732e-01,-6.214573383331298828e-01 --3.383747935295104980e-01,-5.114832520484924316e-01 --3.447978496551513672e-01,-3.973104953765869141e-01 --3.593961596488952637e-01,-2.813705801963806152e-01 --3.452069759368896484e-01,-1.408224999904632568e-01 --3.430855870246887207e-01,-2.797167003154754639e-02 --3.557773530483245850e-01,8.781827986240386963e-02 --3.454015254974365234e-01,2.180240601301193237e-01 --3.463566899299621582e-01,3.361232876777648926e-01 --3.583684861660003662e-01,4.862591624259948730e-01 --3.433609008789062500e-01,6.006531119346618652e-01 --3.413309156894683838e-01,7.142059803009033203e-01 --3.361082673072814941e-01,8.515341281890869141e-01 --3.364007472991943359e-01,9.599573612213134766e-01 --4.831644594669342041e-01,-1.008612871170043945e+00 --4.787659943103790283e-01,-8.623197674751281738e-01 --4.642373919486999512e-01,-7.497129440307617188e-01 --4.642499089241027832e-01,-6.430255174636840820e-01 --4.642372727394104004e-01,-5.121074914932250977e-01 --4.308604300022125244e-01,-3.965112864971160889e-01 --4.636788368225097656e-01,-2.791341245174407959e-01 --4.580321013927459717e-01,-1.335953623056411743e-01 --4.598477482795715332e-01,-1.313996850512921810e-03 --4.628738462924957275e-01,8.805514127016067505e-02 --4.725404381752014160e-01,2.301194816827774048e-01 --4.617980718612670898e-01,3.404323458671569824e-01 --4.771160185337066650e-01,4.645164906978607178e-01 --4.717559516429901123e-01,5.859128236770629883e-01 --4.742413759231567383e-01,7.056457996368408203e-01 --4.685690104961395264e-01,8.372198939323425293e-01 --4.462411701679229736e-01,9.508741497993469238e-01 --6.105093955993652344e-01,-9.972954392433166504e-01 --5.849741101264953613e-01,-8.780534267425537109e-01 --6.079639196395874023e-01,-7.574915289878845215e-01 --5.965560674667358398e-01,-6.417286992073059082e-01 --5.809472203254699707e-01,-5.159717798233032227e-01 --5.911939144134521484e-01,-3.802011907100677490e-01 --6.026141643524169922e-01,-2.602969408035278320e-01 --5.989897847175598145e-01,-1.526326984167098999e-01 --5.850407481193542480e-01,-1.941484026610851288e-02 --5.991404056549072266e-01,1.095546856522560120e-01 --5.896721482276916504e-01,2.077957391738891602e-01 --5.913810133934020996e-01,3.523723781108856201e-01 --5.983527302742004395e-01,4.627615213394165039e-01 --5.703973174095153809e-01,5.975427031517028809e-01 --5.854975581169128418e-01,7.066531181335449219e-01 --6.120881438255310059e-01,8.186858892440795898e-01 --5.899721980094909668e-01,9.429082274436950684e-01 --7.209035754203796387e-01,-9.995191693305969238e-01 --7.057613730430603027e-01,-8.749538064002990723e-01 --7.222109436988830566e-01,-7.641451954841613770e-01 --7.154330611228942871e-01,-6.262671351432800293e-01 --7.092358469963073730e-01,-5.268192887306213379e-01 --7.056281566619873047e-01,-3.884159028530120850e-01 --7.262886762619018555e-01,-2.774162888526916504e-01 --7.176307439804077148e-01,-1.493754982948303223e-01 --7.190351486206054688e-01,-1.993417739868164062e-02 --7.208189964294433594e-01,9.343668073415756226e-02 --6.966311931610107422e-01,2.206442356109619141e-01 --7.102358937263488770e-01,3.570016920566558838e-01 --7.268945574760437012e-01,4.636188447475433350e-01 --7.051070928573608398e-01,6.001936793327331543e-01 --6.930641531944274902e-01,7.029886245727539062e-01 --7.039610743522644043e-01,8.420327305793762207e-01 --7.294794321060180664e-01,9.735993742942810059e-01 --8.415770530700683594e-01,-1.024716496467590332e+00 --8.240655660629272461e-01,-8.855199813842773438e-01 --8.438113927841186523e-01,-7.493312954902648926e-01 --8.322964906692504883e-01,-6.346834897994995117e-01 --8.289883732795715332e-01,-5.064926147460937500e-01 --8.460040092468261719e-01,-3.937949538230895996e-01 --8.373299241065979004e-01,-2.644402384757995605e-01 --8.691473603248596191e-01,-1.444139182567596436e-01 --8.469785451889038086e-01,-8.730342611670494080e-03 --8.392603993415832520e-01,1.045850217342376709e-01 --8.492125272750854492e-01,2.278658151626586914e-01 --8.204106092453002930e-01,3.428200185298919678e-01 --8.510361313819885254e-01,4.645116925239562988e-01 --8.411351442337036133e-01,5.875111818313598633e-01 --8.354272842407226562e-01,7.182302474975585938e-01 --8.223219513893127441e-01,8.325248360633850098e-01 --8.510932922363281250e-01,9.620814323425292969e-01 --9.475520253181457520e-01,-9.792460203170776367e-01 --9.590813517570495605e-01,-8.688398003578186035e-01 --9.689987301826477051e-01,-7.583622932434082031e-01 --9.545626640319824219e-01,-6.206409335136413574e-01 --9.571930766105651855e-01,-5.142848491668701172e-01 --9.651858210563659668e-01,-4.081363379955291748e-01 --9.584856629371643066e-01,-2.753869891166687012e-01 --9.630368351936340332e-01,-1.615650653839111328e-01 --9.580485224723815918e-01,-2.392329834401607513e-02 --9.525623917579650879e-01,1.022249981760978699e-01 --9.433234930038452148e-01,2.412541657686233521e-01 --9.715618491172790527e-01,3.502080440521240234e-01 --9.378533363342285156e-01,4.671967625617980957e-01 --9.787045717239379883e-01,6.001307964324951172e-01 --9.607015252113342285e-01,6.921743750572204590e-01 --9.533004760742187500e-01,8.390908241271972656e-01 --9.563737511634826660e-01,9.668923020362854004e-01 diff --git a/docs/examples/data/UV_train_vortex.csv b/docs/examples/data/UV_train_vortex.csv deleted file mode 100644 index cbee3ff20..000000000 --- a/docs/examples/data/UV_train_vortex.csv +++ /dev/null @@ -1,8 +0,0 @@ --2.307565808296203613e-01,-5.147150158882141113e-01 -7.614375352859497070e-01,-9.592417478561401367e-01 --7.997303605079650879e-01,-7.207061052322387695e-01 --2.541528940200805664e-01,-9.593041539192199707e-01 --6.932516098022460938e-01,-9.331753253936767578e-01 -2.270692773163318634e-02,-8.047766089439392090e-01 -3.859917819499969482e-01,-7.105028629302978516e-01 -9.024822115898132324e-01,-7.966634035110473633e-01 diff --git a/docs/examples/data/XY_test_vortex.csv b/docs/examples/data/XY_test_vortex.csv deleted file mode 100644 index 6d0a4cd02..000000000 --- a/docs/examples/data/XY_test_vortex.csv +++ /dev/null @@ -1,289 +0,0 @@ --1.000000000000000000e+00,-1.000000000000000000e+00 --8.775510191917419434e-01,-1.000000000000000000e+00 --7.551020383834838867e-01,-1.000000000000000000e+00 --6.326530575752258301e-01,-1.000000000000000000e+00 --5.102040767669677734e-01,-1.000000000000000000e+00 --3.877550959587097168e-01,-1.000000000000000000e+00 --2.653061151504516602e-01,-1.000000000000000000e+00 --1.428571492433547974e-01,-1.000000000000000000e+00 --2.040816284716129303e-02,-1.000000000000000000e+00 -1.020408198237419128e-01,-1.000000000000000000e+00 -2.244897931814193726e-01,-1.000000000000000000e+00 -3.469387888908386230e-01,-1.000000000000000000e+00 -4.693877696990966797e-01,-1.000000000000000000e+00 -5.918367505073547363e-01,-1.000000000000000000e+00 -7.142857313156127930e-01,-1.000000000000000000e+00 -8.367347121238708496e-01,-1.000000000000000000e+00 -9.591836929321289062e-01,-1.000000000000000000e+00 --1.000000000000000000e+00,-8.775510191917419434e-01 --8.775510191917419434e-01,-8.775510191917419434e-01 --7.551020383834838867e-01,-8.775510191917419434e-01 --6.326530575752258301e-01,-8.775510191917419434e-01 --5.102040767669677734e-01,-8.775510191917419434e-01 --3.877550959587097168e-01,-8.775510191917419434e-01 --2.653061151504516602e-01,-8.775510191917419434e-01 --1.428571492433547974e-01,-8.775510191917419434e-01 --2.040816284716129303e-02,-8.775510191917419434e-01 -1.020408198237419128e-01,-8.775510191917419434e-01 -2.244897931814193726e-01,-8.775510191917419434e-01 -3.469387888908386230e-01,-8.775510191917419434e-01 -4.693877696990966797e-01,-8.775510191917419434e-01 -5.918367505073547363e-01,-8.775510191917419434e-01 -7.142857313156127930e-01,-8.775510191917419434e-01 -8.367347121238708496e-01,-8.775510191917419434e-01 -9.591836929321289062e-01,-8.775510191917419434e-01 --1.000000000000000000e+00,-7.551020383834838867e-01 --8.775510191917419434e-01,-7.551020383834838867e-01 --7.551020383834838867e-01,-7.551020383834838867e-01 --6.326530575752258301e-01,-7.551020383834838867e-01 --5.102040767669677734e-01,-7.551020383834838867e-01 --3.877550959587097168e-01,-7.551020383834838867e-01 --2.653061151504516602e-01,-7.551020383834838867e-01 --1.428571492433547974e-01,-7.551020383834838867e-01 --2.040816284716129303e-02,-7.551020383834838867e-01 -1.020408198237419128e-01,-7.551020383834838867e-01 -2.244897931814193726e-01,-7.551020383834838867e-01 -3.469387888908386230e-01,-7.551020383834838867e-01 -4.693877696990966797e-01,-7.551020383834838867e-01 -5.918367505073547363e-01,-7.551020383834838867e-01 -7.142857313156127930e-01,-7.551020383834838867e-01 -8.367347121238708496e-01,-7.551020383834838867e-01 -9.591836929321289062e-01,-7.551020383834838867e-01 --1.000000000000000000e+00,-6.326530575752258301e-01 --8.775510191917419434e-01,-6.326530575752258301e-01 --7.551020383834838867e-01,-6.326530575752258301e-01 --6.326530575752258301e-01,-6.326530575752258301e-01 --5.102040767669677734e-01,-6.326530575752258301e-01 --3.877550959587097168e-01,-6.326530575752258301e-01 --2.653061151504516602e-01,-6.326530575752258301e-01 --1.428571492433547974e-01,-6.326530575752258301e-01 --2.040816284716129303e-02,-6.326530575752258301e-01 -1.020408198237419128e-01,-6.326530575752258301e-01 -2.244897931814193726e-01,-6.326530575752258301e-01 -3.469387888908386230e-01,-6.326530575752258301e-01 -4.693877696990966797e-01,-6.326530575752258301e-01 -5.918367505073547363e-01,-6.326530575752258301e-01 -7.142857313156127930e-01,-6.326530575752258301e-01 -8.367347121238708496e-01,-6.326530575752258301e-01 -9.591836929321289062e-01,-6.326530575752258301e-01 --1.000000000000000000e+00,-5.102040767669677734e-01 --8.775510191917419434e-01,-5.102040767669677734e-01 --7.551020383834838867e-01,-5.102040767669677734e-01 --6.326530575752258301e-01,-5.102040767669677734e-01 --5.102040767669677734e-01,-5.102040767669677734e-01 --3.877550959587097168e-01,-5.102040767669677734e-01 --2.653061151504516602e-01,-5.102040767669677734e-01 --1.428571492433547974e-01,-5.102040767669677734e-01 --2.040816284716129303e-02,-5.102040767669677734e-01 -1.020408198237419128e-01,-5.102040767669677734e-01 -2.244897931814193726e-01,-5.102040767669677734e-01 -3.469387888908386230e-01,-5.102040767669677734e-01 -4.693877696990966797e-01,-5.102040767669677734e-01 -5.918367505073547363e-01,-5.102040767669677734e-01 -7.142857313156127930e-01,-5.102040767669677734e-01 -8.367347121238708496e-01,-5.102040767669677734e-01 -9.591836929321289062e-01,-5.102040767669677734e-01 --1.000000000000000000e+00,-3.877550959587097168e-01 --8.775510191917419434e-01,-3.877550959587097168e-01 --7.551020383834838867e-01,-3.877550959587097168e-01 --6.326530575752258301e-01,-3.877550959587097168e-01 --5.102040767669677734e-01,-3.877550959587097168e-01 --3.877550959587097168e-01,-3.877550959587097168e-01 --2.653061151504516602e-01,-3.877550959587097168e-01 --1.428571492433547974e-01,-3.877550959587097168e-01 --2.040816284716129303e-02,-3.877550959587097168e-01 -1.020408198237419128e-01,-3.877550959587097168e-01 -2.244897931814193726e-01,-3.877550959587097168e-01 -3.469387888908386230e-01,-3.877550959587097168e-01 -4.693877696990966797e-01,-3.877550959587097168e-01 -5.918367505073547363e-01,-3.877550959587097168e-01 -7.142857313156127930e-01,-3.877550959587097168e-01 -8.367347121238708496e-01,-3.877550959587097168e-01 -9.591836929321289062e-01,-3.877550959587097168e-01 --1.000000000000000000e+00,-2.653061151504516602e-01 --8.775510191917419434e-01,-2.653061151504516602e-01 --7.551020383834838867e-01,-2.653061151504516602e-01 --6.326530575752258301e-01,-2.653061151504516602e-01 --5.102040767669677734e-01,-2.653061151504516602e-01 --3.877550959587097168e-01,-2.653061151504516602e-01 --2.653061151504516602e-01,-2.653061151504516602e-01 --1.428571492433547974e-01,-2.653061151504516602e-01 --2.040816284716129303e-02,-2.653061151504516602e-01 -1.020408198237419128e-01,-2.653061151504516602e-01 -2.244897931814193726e-01,-2.653061151504516602e-01 -3.469387888908386230e-01,-2.653061151504516602e-01 -4.693877696990966797e-01,-2.653061151504516602e-01 -5.918367505073547363e-01,-2.653061151504516602e-01 -7.142857313156127930e-01,-2.653061151504516602e-01 -8.367347121238708496e-01,-2.653061151504516602e-01 -9.591836929321289062e-01,-2.653061151504516602e-01 --1.000000000000000000e+00,-1.428571492433547974e-01 --8.775510191917419434e-01,-1.428571492433547974e-01 --7.551020383834838867e-01,-1.428571492433547974e-01 --6.326530575752258301e-01,-1.428571492433547974e-01 --5.102040767669677734e-01,-1.428571492433547974e-01 --3.877550959587097168e-01,-1.428571492433547974e-01 --2.653061151504516602e-01,-1.428571492433547974e-01 --1.428571492433547974e-01,-1.428571492433547974e-01 --2.040816284716129303e-02,-1.428571492433547974e-01 -1.020408198237419128e-01,-1.428571492433547974e-01 -2.244897931814193726e-01,-1.428571492433547974e-01 -3.469387888908386230e-01,-1.428571492433547974e-01 -4.693877696990966797e-01,-1.428571492433547974e-01 -5.918367505073547363e-01,-1.428571492433547974e-01 -7.142857313156127930e-01,-1.428571492433547974e-01 -8.367347121238708496e-01,-1.428571492433547974e-01 -9.591836929321289062e-01,-1.428571492433547974e-01 --1.000000000000000000e+00,-2.040816284716129303e-02 --8.775510191917419434e-01,-2.040816284716129303e-02 --7.551020383834838867e-01,-2.040816284716129303e-02 --6.326530575752258301e-01,-2.040816284716129303e-02 --5.102040767669677734e-01,-2.040816284716129303e-02 --3.877550959587097168e-01,-2.040816284716129303e-02 --2.653061151504516602e-01,-2.040816284716129303e-02 --1.428571492433547974e-01,-2.040816284716129303e-02 --2.040816284716129303e-02,-2.040816284716129303e-02 -1.020408198237419128e-01,-2.040816284716129303e-02 -2.244897931814193726e-01,-2.040816284716129303e-02 -3.469387888908386230e-01,-2.040816284716129303e-02 -4.693877696990966797e-01,-2.040816284716129303e-02 -5.918367505073547363e-01,-2.040816284716129303e-02 -7.142857313156127930e-01,-2.040816284716129303e-02 -8.367347121238708496e-01,-2.040816284716129303e-02 -9.591836929321289062e-01,-2.040816284716129303e-02 --1.000000000000000000e+00,1.020408198237419128e-01 --8.775510191917419434e-01,1.020408198237419128e-01 --7.551020383834838867e-01,1.020408198237419128e-01 --6.326530575752258301e-01,1.020408198237419128e-01 --5.102040767669677734e-01,1.020408198237419128e-01 --3.877550959587097168e-01,1.020408198237419128e-01 --2.653061151504516602e-01,1.020408198237419128e-01 --1.428571492433547974e-01,1.020408198237419128e-01 --2.040816284716129303e-02,1.020408198237419128e-01 -1.020408198237419128e-01,1.020408198237419128e-01 -2.244897931814193726e-01,1.020408198237419128e-01 -3.469387888908386230e-01,1.020408198237419128e-01 -4.693877696990966797e-01,1.020408198237419128e-01 -5.918367505073547363e-01,1.020408198237419128e-01 -7.142857313156127930e-01,1.020408198237419128e-01 -8.367347121238708496e-01,1.020408198237419128e-01 -9.591836929321289062e-01,1.020408198237419128e-01 --1.000000000000000000e+00,2.244897931814193726e-01 --8.775510191917419434e-01,2.244897931814193726e-01 --7.551020383834838867e-01,2.244897931814193726e-01 --6.326530575752258301e-01,2.244897931814193726e-01 --5.102040767669677734e-01,2.244897931814193726e-01 --3.877550959587097168e-01,2.244897931814193726e-01 --2.653061151504516602e-01,2.244897931814193726e-01 --1.428571492433547974e-01,2.244897931814193726e-01 --2.040816284716129303e-02,2.244897931814193726e-01 -1.020408198237419128e-01,2.244897931814193726e-01 -2.244897931814193726e-01,2.244897931814193726e-01 -3.469387888908386230e-01,2.244897931814193726e-01 -4.693877696990966797e-01,2.244897931814193726e-01 -5.918367505073547363e-01,2.244897931814193726e-01 -7.142857313156127930e-01,2.244897931814193726e-01 -8.367347121238708496e-01,2.244897931814193726e-01 -9.591836929321289062e-01,2.244897931814193726e-01 --1.000000000000000000e+00,3.469387888908386230e-01 --8.775510191917419434e-01,3.469387888908386230e-01 --7.551020383834838867e-01,3.469387888908386230e-01 --6.326530575752258301e-01,3.469387888908386230e-01 --5.102040767669677734e-01,3.469387888908386230e-01 --3.877550959587097168e-01,3.469387888908386230e-01 --2.653061151504516602e-01,3.469387888908386230e-01 --1.428571492433547974e-01,3.469387888908386230e-01 --2.040816284716129303e-02,3.469387888908386230e-01 -1.020408198237419128e-01,3.469387888908386230e-01 -2.244897931814193726e-01,3.469387888908386230e-01 -3.469387888908386230e-01,3.469387888908386230e-01 -4.693877696990966797e-01,3.469387888908386230e-01 -5.918367505073547363e-01,3.469387888908386230e-01 -7.142857313156127930e-01,3.469387888908386230e-01 -8.367347121238708496e-01,3.469387888908386230e-01 -9.591836929321289062e-01,3.469387888908386230e-01 --1.000000000000000000e+00,4.693877696990966797e-01 --8.775510191917419434e-01,4.693877696990966797e-01 --7.551020383834838867e-01,4.693877696990966797e-01 --6.326530575752258301e-01,4.693877696990966797e-01 --5.102040767669677734e-01,4.693877696990966797e-01 --3.877550959587097168e-01,4.693877696990966797e-01 --2.653061151504516602e-01,4.693877696990966797e-01 --1.428571492433547974e-01,4.693877696990966797e-01 --2.040816284716129303e-02,4.693877696990966797e-01 -1.020408198237419128e-01,4.693877696990966797e-01 -2.244897931814193726e-01,4.693877696990966797e-01 -3.469387888908386230e-01,4.693877696990966797e-01 -4.693877696990966797e-01,4.693877696990966797e-01 -5.918367505073547363e-01,4.693877696990966797e-01 -7.142857313156127930e-01,4.693877696990966797e-01 -8.367347121238708496e-01,4.693877696990966797e-01 -9.591836929321289062e-01,4.693877696990966797e-01 --1.000000000000000000e+00,5.918367505073547363e-01 --8.775510191917419434e-01,5.918367505073547363e-01 --7.551020383834838867e-01,5.918367505073547363e-01 --6.326530575752258301e-01,5.918367505073547363e-01 --5.102040767669677734e-01,5.918367505073547363e-01 --3.877550959587097168e-01,5.918367505073547363e-01 --2.653061151504516602e-01,5.918367505073547363e-01 --1.428571492433547974e-01,5.918367505073547363e-01 --2.040816284716129303e-02,5.918367505073547363e-01 -1.020408198237419128e-01,5.918367505073547363e-01 -2.244897931814193726e-01,5.918367505073547363e-01 -3.469387888908386230e-01,5.918367505073547363e-01 -4.693877696990966797e-01,5.918367505073547363e-01 -5.918367505073547363e-01,5.918367505073547363e-01 -7.142857313156127930e-01,5.918367505073547363e-01 -8.367347121238708496e-01,5.918367505073547363e-01 -9.591836929321289062e-01,5.918367505073547363e-01 --1.000000000000000000e+00,7.142857313156127930e-01 --8.775510191917419434e-01,7.142857313156127930e-01 --7.551020383834838867e-01,7.142857313156127930e-01 --6.326530575752258301e-01,7.142857313156127930e-01 --5.102040767669677734e-01,7.142857313156127930e-01 --3.877550959587097168e-01,7.142857313156127930e-01 --2.653061151504516602e-01,7.142857313156127930e-01 --1.428571492433547974e-01,7.142857313156127930e-01 --2.040816284716129303e-02,7.142857313156127930e-01 -1.020408198237419128e-01,7.142857313156127930e-01 -2.244897931814193726e-01,7.142857313156127930e-01 -3.469387888908386230e-01,7.142857313156127930e-01 -4.693877696990966797e-01,7.142857313156127930e-01 -5.918367505073547363e-01,7.142857313156127930e-01 -7.142857313156127930e-01,7.142857313156127930e-01 -8.367347121238708496e-01,7.142857313156127930e-01 -9.591836929321289062e-01,7.142857313156127930e-01 --1.000000000000000000e+00,8.367347121238708496e-01 --8.775510191917419434e-01,8.367347121238708496e-01 --7.551020383834838867e-01,8.367347121238708496e-01 --6.326530575752258301e-01,8.367347121238708496e-01 --5.102040767669677734e-01,8.367347121238708496e-01 --3.877550959587097168e-01,8.367347121238708496e-01 --2.653061151504516602e-01,8.367347121238708496e-01 --1.428571492433547974e-01,8.367347121238708496e-01 --2.040816284716129303e-02,8.367347121238708496e-01 -1.020408198237419128e-01,8.367347121238708496e-01 -2.244897931814193726e-01,8.367347121238708496e-01 -3.469387888908386230e-01,8.367347121238708496e-01 -4.693877696990966797e-01,8.367347121238708496e-01 -5.918367505073547363e-01,8.367347121238708496e-01 -7.142857313156127930e-01,8.367347121238708496e-01 -8.367347121238708496e-01,8.367347121238708496e-01 -9.591836929321289062e-01,8.367347121238708496e-01 --1.000000000000000000e+00,9.591836929321289062e-01 --8.775510191917419434e-01,9.591836929321289062e-01 --7.551020383834838867e-01,9.591836929321289062e-01 --6.326530575752258301e-01,9.591836929321289062e-01 --5.102040767669677734e-01,9.591836929321289062e-01 --3.877550959587097168e-01,9.591836929321289062e-01 --2.653061151504516602e-01,9.591836929321289062e-01 --1.428571492433547974e-01,9.591836929321289062e-01 --2.040816284716129303e-02,9.591836929321289062e-01 -1.020408198237419128e-01,9.591836929321289062e-01 -2.244897931814193726e-01,9.591836929321289062e-01 -3.469387888908386230e-01,9.591836929321289062e-01 -4.693877696990966797e-01,9.591836929321289062e-01 -5.918367505073547363e-01,9.591836929321289062e-01 -7.142857313156127930e-01,9.591836929321289062e-01 -8.367347121238708496e-01,9.591836929321289062e-01 -9.591836929321289062e-01,9.591836929321289062e-01 diff --git a/docs/examples/data/XY_train_vortex.csv b/docs/examples/data/XY_train_vortex.csv deleted file mode 100644 index 10916c6e1..000000000 --- a/docs/examples/data/XY_train_vortex.csv +++ /dev/null @@ -1,8 +0,0 @@ --8.999999761581420898e-01,8.999999761581420898e-01 --9.499999880790710449e-01,-7.500000000000000000e-01 --6.999999880790710449e-01,8.000000119209289551e-01 --9.499999880790710449e-01,2.500000000000000000e-01 --9.499999880790710449e-01,6.999999880790710449e-01 --8.000000119209289551e-01,0.000000000000000000e+00 --7.020655274391174316e-01,-3.841731250286102295e-01 --8.000000119209289551e-01,-8.999999761581420898e-01 diff --git a/docs/examples/data/gulfdata_test.csv b/docs/examples/data/gulfdata_test.csv new file mode 100644 index 000000000..313c4793a --- /dev/null +++ b/docs/examples/data/gulfdata_test.csv @@ -0,0 +1,545 @@ +,lon,lat,ubar,vbar,shape +0,-90.78823529,24.03125,0.012934734,-0.119138002,34 +1,-90.57647059,24.03125,-0.048447536,-0.053945304,16 +2,-90.36470588,24.03125,-0.063418192,0.009081421,0 +3,-90.15294118,24.03125,-0.079781553,-0.052787458,0 +4,-89.94117647,24.03125,-0.037646996,-0.067648494,0 +5,-89.72941176,24.03125,-0.013759543,-0.050209018,0 +6,-89.51764706,24.03125,-0.056024482,-0.07421219,0 +7,-89.30588235,24.03125,-0.040638775,-0.07613701,0 +8,-89.09411765,24.03125,-0.050733638,-0.015584665,0 +9,-88.88235294,24.03125,-0.029212873,-0.036183464,0 +10,-88.67058824,24.03125,-0.037372362,-0.156029259,0 +11,-88.45882353,24.03125,-0.01494416,-0.06919967,0 +12,-88.24705882,24.03125,-0.062871325,-0.012938229,0 +13,-88.03529412,24.03125,-0.109551896,0.018954081,0 +14,-87.82352941,24.03125,-0.269340276,-0.074616515,0 +15,-87.61176471,24.03125,-0.313617175,0.114040312,0 +16,-87.4,24.03125,-0.467162405,0.301118178,0 +17,-87.18823529,24.03125,-0.438090893,0.288097941,0 +18,-86.97647059,24.03125,-0.295175025,0.398262865,0 +19,-86.76470588,24.03125,-0.07773377,0.026426916,0 +20,-86.55294118,24.03125,-0.049904935,-0.013369981,0 +21,-86.34117647,24.03125,-0.010054117,-0.015447627,0 +22,-86.12941176,24.03125,-0.059930947,0.060322613,0 +23,-85.91764706,24.03125,-0.079267656,-0.027754038,0 +24,-85.70588235,24.03125,-0.001990859,-0.030039107,0 +25,-85.49411765,24.03125,0.139947451,-0.097313427,0 +26,-85.28235294,24.03125,0.203027776,-0.034414591,0 +27,-85.07058824,24.03125,0.18490045,-0.180825723,0 +28,-84.85882353,24.03125,0.259426357,-0.255191914,0 +29,-84.64705882,24.03125,0.403989777,-0.344969787,0 +30,-84.43529412,24.03125,0.418881952,-0.306396519,0 +31,-84.22352941,24.03125,0.401640041,-0.279468744,0 +32,-84.01176471,24.03125,0.405423791,-0.281736808,0 +33,-83.8,24.03125,0.300436065,-0.25017157,0 +34,-90.78823529,24.2625,-0.001970387,-0.048574076,0 +35,-90.57647059,24.2625,-0.012415587,-0.036935943,0 +36,-90.36470588,24.2625,0.003214217,-0.059640195,0 +37,-90.15294118,24.2625,0.048173025,-0.040376054,0 +38,-89.94117647,24.2625,0.021711527,-0.060253566,0 +39,-89.72941176,24.2625,0.014017724,-0.087975435,0 +40,-89.51764706,24.2625,0.111103018,-0.099072446,0 +41,-89.30588235,24.2625,0.063349561,-0.10544855,0 +42,-89.09411765,24.2625,0.080851702,-0.053605717,0 +43,-88.88235294,24.2625,0.17987771,-0.187315712,0 +44,-88.67058824,24.2625,0.148566514,-0.202426321,0 +45,-88.45882353,24.2625,0.076863273,0.00234853,0 +46,-88.24705882,24.2625,0.033361642,0.043027404,0 +47,-88.03529412,24.2625,-0.094032501,0.092244477,0 +48,-87.82352941,24.2625,-0.352788048,0.222832158,0 +49,-87.61176471,24.2625,-0.527584387,0.319983483,0 +50,-87.4,24.2625,-0.31815162,0.075536871,0 +51,-87.18823529,24.2625,-0.378981038,0.080490224,0 +52,-86.97647059,24.2625,-0.230711752,0.081317482,0 +53,-86.76470588,24.2625,-0.073356462,-0.038011937,0 +54,-86.55294118,24.2625,-0.055855093,-0.028346203,0 +55,-86.34117647,24.2625,-0.13545188,0.086092559,0 +56,-86.12941176,24.2625,-0.048275949,0.03036671,0 +57,-85.91764706,24.2625,-0.031056324,0.000444703,0 +58,-85.70588235,24.2625,-0.097879193,-0.15157636,0 +59,-85.49411765,24.2625,-0.032475112,-0.265242133,0 +60,-85.28235294,24.2625,0.086591979,-0.134721176,0 +61,-85.07058824,24.2625,0.129215449,-0.151881538,0 +62,-84.85882353,24.2625,0.215008841,-0.277468569,0 +63,-84.64705882,24.2625,0.346628287,-0.392841735,0 +64,-84.43529412,24.2625,0.261683327,-0.234586921,0 +65,-84.22352941,24.2625,0.220448207,-0.252728914,0 +66,-84.01176471,24.2625,0.289019892,-0.223931847,0 +67,-83.8,24.2625,0.221771131,-0.209547007,0 +68,-90.78823529,24.49375,-0.107406962,-0.049236746,0 +69,-90.57647059,24.49375,-0.073294697,-0.088041875,0 +70,-90.36470588,24.49375,-0.032563777,-0.076576075,0 +71,-90.15294118,24.49375,-0.029756774,-0.100970247,0 +72,-89.94117647,24.49375,0.00864684,-0.074296756,0 +73,-89.72941176,24.49375,0.057434301,-0.165396174,0 +74,-89.51764706,24.49375,0.082839096,-0.11400015,0 +75,-89.30588235,24.49375,0.289836275,-0.217025145,0 +76,-89.09411765,24.49375,0.369932663,-0.201184574,0 +77,-88.88235294,24.49375,0.336533257,-0.190465581,0 +78,-88.67058824,24.49375,0.133076887,0.023502245,0 +79,-88.45882353,24.49375,0.092060005,0.053315308,0 +80,-88.24705882,24.49375,0.035149461,0.116643541,0 +81,-88.03529412,24.49375,-0.045901414,0.225121066,0 +82,-87.82352941,24.49375,-0.299234418,0.349037405,0 +83,-87.61176471,24.49375,-0.445357905,0.464884889,0 +84,-87.4,24.49375,-0.246941376,0.130840473,0 +85,-87.18823529,24.49375,-0.322251609,0.108879502,0 +86,-86.97647059,24.49375,-0.221729518,-0.142641746,0 +87,-86.76470588,24.49375,-0.180857265,-0.073733515,0 +88,-86.55294118,24.49375,-0.29547835,0.077388131,0 +89,-86.34117647,24.49375,-0.262170615,-0.03014991,0 +90,-86.12941176,24.49375,-0.195716753,0.016608455,0 +91,-85.91764706,24.49375,-0.049866945,-0.024089298,0 +92,-85.70588235,24.49375,-0.018318565,-0.165395019,0 +93,-85.49411765,24.49375,0.015679874,-0.192181915,0 +94,-85.28235294,24.49375,-0.03550123,-0.236503143,0 +95,-85.07058824,24.49375,0.080393272,-0.106866696,0 +96,-84.85882353,24.49375,0.067912807,-0.28282864,0 +97,-84.64705882,24.49375,0.199518282,-0.407025005,0 +98,-84.43529412,24.49375,0.193570146,-0.137194872,0 +99,-84.22352941,24.49375,0.157749543,-0.186695753,0 +100,-84.01176471,24.49375,0.187017952,-0.288034057,0 +101,-83.8,24.49375,0.180010234,-0.145048261,0 +102,-90.78823529,24.725,-0.001920843,-0.057100952,0 +103,-90.57647059,24.725,-0.005202058,-0.062615868,0 +104,-90.36470588,24.725,-0.018122687,-0.160703595,0 +105,-90.15294118,24.725,0.022168602,-0.147095471,0 +106,-89.94117647,24.725,0.098186242,-0.200168604,0 +107,-89.72941176,24.725,0.114127181,-0.257008367,0 +108,-89.51764706,24.725,0.288965519,-0.24562694,0 +109,-89.30588235,24.725,0.366871235,-0.310349972,0 +110,-89.09411765,24.725,0.316964648,-0.167555442,0 +111,-88.88235294,24.725,0.093938286,0.099809033,0 +112,-88.67058824,24.725,0.032558011,0.124588301,0 +113,-88.45882353,24.725,-0.045144374,0.164408293,0 +114,-88.24705882,24.725,-0.104119643,0.238643039,0 +115,-88.03529412,24.725,-0.159232622,0.2970519,0 +116,-87.82352941,24.725,-0.481320719,0.591122739,0 +117,-87.61176471,24.725,-0.210899216,0.164175907,0 +118,-87.4,24.725,-0.29225526,0.200847558,0 +119,-87.18823529,24.725,-0.253726305,0.159467611,0 +120,-86.97647059,24.725,-0.234049572,-0.061609694,0 +121,-86.76470588,24.725,-0.355413504,-0.13213955,0 +122,-86.55294118,24.725,-0.32187465,-0.093146523,0 +123,-86.34117647,24.725,-0.144105695,-0.117690733,0 +124,-86.12941176,24.725,-0.0199346,-0.067486114,0 +125,-85.91764706,24.725,-0.037872691,-0.187187884,0 +126,-85.70588235,24.725,0.010437814,-0.17594918,0 +127,-85.49411765,24.725,0.052576319,-0.252479388,0 +128,-85.28235294,24.725,0.042249791,-0.283942508,0 +129,-85.07058824,24.725,0.004013188,-0.289127388,0 +130,-84.85882353,24.725,0.048345871,-0.309461433,0 +131,-84.64705882,24.725,0.097446268,-0.455497697,0 +132,-84.43529412,24.725,0.091244058,-0.164644918,0 +133,-84.22352941,24.725,0.137958525,-0.194290947,0 +134,-84.01176471,24.725,0.11270575,-0.214570236,0 +135,-83.8,24.725,0.04446445,-0.065173442,0 +136,-90.78823529,24.95625,-0.068671315,-0.070961189,0 +137,-90.57647059,24.95625,-0.062771404,-0.093159722,0 +138,-90.36470588,24.95625,-0.007674697,-0.203497023,0 +139,-90.15294118,24.95625,0.0270646,-0.123043403,0 +140,-89.94117647,24.95625,-0.001125839,-0.159442335,0 +141,-89.72941176,24.95625,0.155152339,-0.299351029,0 +142,-89.51764706,24.95625,0.20747634,-0.338449702,0 +143,-89.30588235,24.95625,0.127189226,-0.203436091,0 +144,-89.09411765,24.95625,-0.002304782,0.009427787,0 +145,-88.88235294,24.95625,-0.021486956,0.197988496,0 +146,-88.67058824,24.95625,-0.065733465,0.212740665,0 +147,-88.45882353,24.95625,-0.114057704,0.21722011,0 +148,-88.24705882,24.95625,-0.155708378,0.268737791,0 +149,-88.03529412,24.95625,-0.080807704,0.231927877,0 +150,-87.82352941,24.95625,-0.147157954,0.291938004,0 +151,-87.61176471,24.95625,-0.212221319,0.222802073,0 +152,-87.4,24.95625,-0.227550983,0.286225784,0 +153,-87.18823529,24.95625,-0.283724468,0.181675988,0 +154,-86.97647059,24.95625,-0.110271126,-0.078571338,0 +155,-86.76470588,24.95625,-0.182219119,-0.213026957,0 +156,-86.55294118,24.95625,-0.191750055,-0.230042074,0 +157,-86.34117647,24.95625,-0.21463129,-0.176883138,0 +158,-86.12941176,24.95625,-0.107571021,-0.15642493,0 +159,-85.91764706,24.95625,0.012545381,-0.216788815,0 +160,-85.70588235,24.95625,0.081749417,-0.278183667,0 +161,-85.49411765,24.95625,0.028316619,-0.289940992,0 +162,-85.28235294,24.95625,0.053155096,-0.290313879,0 +163,-85.07058824,24.95625,-0.006158111,-0.232317753,0 +164,-84.85882353,24.95625,0.030940432,-0.367238532,0 +165,-84.64705882,24.95625,-0.015491593,-0.295685535,0 +166,-84.43529412,24.95625,0.011379354,-0.238575767,0 +167,-84.22352941,24.95625,0.055387965,-0.274255734,0 +168,-84.01176471,24.95625,0.05214515,-0.117859951,0 +169,-83.8,24.95625,-0.0080579,-0.011900092,0 +170,-90.78823529,25.1875,-0.12432471,-0.117731685,0 +171,-90.57647059,25.1875,-0.174591484,-0.131972206,0 +172,-90.36470588,25.1875,-0.144562862,-0.312662359,0 +173,-90.15294118,25.1875,-0.071969315,-0.206957357,0 +174,-89.94117647,25.1875,-0.073665569,-0.186713773,0 +175,-89.72941176,25.1875,-0.131147151,-0.448172793,0 +176,-89.51764706,25.1875,0.018620377,-0.331644793,0 +177,-89.30588235,25.1875,0.009998903,-0.119112152,0 +178,-89.09411765,25.1875,-0.073074476,0.054603658,0 +179,-88.88235294,25.1875,-0.105464374,0.157114053,0 +180,-88.67058824,25.1875,-0.080341096,0.285757799,0 +181,-88.45882353,25.1875,-0.082986553,0.306411888,0 +182,-88.24705882,25.1875,-0.104068303,0.275476961,0 +183,-88.03529412,25.1875,-0.052277643,0.180606565,0 +184,-87.82352941,25.1875,-0.102496127,0.265649837,0 +185,-87.61176471,25.1875,-0.114445904,0.407122675,0 +186,-87.4,25.1875,-0.111313983,0.264506462,0 +187,-87.18823529,25.1875,-0.05183303,0.080687298,0 +188,-86.97647059,25.1875,-0.039709437,-0.123221653,0 +189,-86.76470588,25.1875,-0.031455607,-0.117034118,0 +190,-86.55294118,25.1875,-0.072164475,-0.061583073,0 +191,-86.34117647,25.1875,-0.134109372,-0.185987084,0 +192,-86.12941176,25.1875,-0.144734126,-0.261783824,0 +193,-85.91764706,25.1875,-0.035302626,-0.297357451,0 +194,-85.70588235,25.1875,0.082609131,-0.320545628,0 +195,-85.49411765,25.1875,0.03083069,-0.212149475,0 +196,-85.28235294,25.1875,0.000866022,-0.252272292,0 +197,-85.07058824,25.1875,0.071537092,-0.344332424,0 +198,-84.85882353,25.1875,0.03155944,-0.399977404,0 +199,-84.64705882,25.1875,0.08220279,-0.368149906,0 +200,-84.43529412,25.1875,-0.032850763,-0.236765644,0 +201,-84.22352941,25.1875,-0.048986644,-0.25707726,0 +202,-84.01176471,25.1875,-0.059588521,-0.090060442,0 +203,-83.8,25.1875,-0.057199879,-0.049451263,0 +204,-90.78823529,25.41875,-0.132358362,-0.087289275,0 +205,-90.57647059,25.41875,-0.202081522,-0.125632991,0 +206,-90.36470588,25.41875,-0.216905583,-0.212145558,0 +207,-90.15294118,25.41875,-0.165846871,-0.232816711,0 +208,-89.94117647,25.41875,-0.136376108,-0.256474579,0 +209,-89.72941176,25.41875,-0.143006764,-0.471258778,0 +210,-89.51764706,25.41875,-0.116104577,-0.44676606,0 +211,-89.30588235,25.41875,-0.05307556,-0.065772887,0 +212,-89.09411765,25.41875,-0.063669139,0.124027217,0 +213,-88.88235294,25.41875,-0.100326703,0.186230618,0 +214,-88.67058824,25.41875,-0.086277437,0.272444831,0 +215,-88.45882353,25.41875,0.006588612,0.248742571,0 +216,-88.24705882,25.41875,0.036745925,0.262806039,0 +217,-88.03529412,25.41875,-0.000240312,0.20942527,0 +218,-87.82352941,25.41875,0.108715689,0.211728295,0 +219,-87.61176471,25.41875,0.040306395,0.346730418,0 +220,-87.4,25.41875,0.021907225,0.373667956,0 +221,-87.18823529,25.41875,0.096129114,-0.012310808,0 +222,-86.97647059,25.41875,0.058595472,-0.083412856,0 +223,-86.76470588,25.41875,0.147405198,-0.087404083,0 +224,-86.55294118,25.41875,0.124921196,-0.114008829,0 +225,-86.34117647,25.41875,0.069967211,-0.162582809,0 +226,-86.12941176,25.41875,0.205385343,-0.258467212,0 +227,-85.91764706,25.41875,0.033662121,-0.279081569,0 +228,-85.70588235,25.41875,-0.098726156,-0.350882919,0 +229,-85.49411765,25.41875,0.018397882,-0.277828386,0 +230,-85.28235294,25.41875,0.077132458,-0.335538009,0 +231,-85.07058824,25.41875,0.046162657,-0.467845926,0 +232,-84.85882353,25.41875,0.017603575,-0.383941281,0 +233,-84.64705882,25.41875,-0.039346258,-0.285323483,0 +234,-84.43529412,25.41875,-0.019037244,-0.239963698,0 +235,-84.22352941,25.41875,-0.054063007,-0.195310247,0 +236,-84.01176471,25.41875,-0.065863705,-0.093853611,0 +237,-83.8,25.41875,-0.054659494,-0.04142678,0 +238,-90.78823529,25.65,-0.261424878,-0.105294813,0 +239,-90.57647059,25.65,-0.21708168,-0.067574425,0 +240,-90.36470588,25.65,-0.1705854,-0.121787582,0 +241,-90.15294118,25.65,-0.21769884,-0.244759145,0 +242,-89.94117647,25.65,-0.221300657,-0.285468652,0 +243,-89.72941176,25.65,-0.143047053,-0.278902819,0 +244,-89.51764706,25.65,-0.154745376,-0.558645986,0 +245,-89.30588235,25.65,-0.066653394,-0.186500112,0 +246,-89.09411765,25.65,-0.058375747,0.099949004,0 +247,-88.88235294,25.65,-0.023507122,0.158206945,0 +248,-88.67058824,25.65,-0.044026717,0.189984867,0 +249,-88.45882353,25.65,-0.021099937,0.324524058,0 +250,-88.24705882,25.65,0.003162908,0.252266646,0 +251,-88.03529412,25.65,0.076919374,0.286853648,0 +252,-87.82352941,25.65,0.059418464,0.142062396,0 +253,-87.61176471,25.65,0.153557224,0.337575841,0 +254,-87.4,25.65,0.210838451,0.374218887,0 +255,-87.18823529,25.65,0.119040151,-0.05485577,0 +256,-86.97647059,25.65,0.124045522,-0.088413895,0 +257,-86.76470588,25.65,0.160107748,-0.082785734,0 +258,-86.55294118,25.65,0.216409423,-0.067934909,0 +259,-86.34117647,25.65,0.200635283,-0.120532465,0 +260,-86.12941176,25.65,0.250672376,-0.163575534,0 +261,-85.91764706,25.65,0.274983119,-0.115574241,0 +262,-85.70588235,25.65,0.353606617,-0.191219611,0 +263,-85.49411765,25.65,0.147884159,-0.345352765,0 +264,-85.28235294,25.65,0.142828267,-0.254648914,0 +265,-85.07058824,25.65,0.149878332,-0.386357103,0 +266,-84.85882353,25.65,0.079479562,-0.3218503,0 +267,-84.64705882,25.65,-0.039876229,-0.322739291,0 +268,-84.43529412,25.65,-0.020601203,-0.258910138,0 +269,-84.22352941,25.65,-0.030342452,-0.141943145,0 +270,-84.01176471,25.65,-0.026403279,-0.116659437,0 +271,-83.8,25.65,-0.028221576,-0.062310204,0 +272,-90.78823529,25.88125,-0.124851721,-0.128636466,0 +273,-90.57647059,25.88125,-0.168870093,-0.08999443,0 +274,-90.36470588,25.88125,-0.17231575,-0.165715883,0 +275,-90.15294118,25.88125,-0.152776566,-0.200739554,0 +276,-89.94117647,25.88125,-0.176438638,-0.24819344,0 +277,-89.72941176,25.88125,-0.133104814,-0.33179839,0 +278,-89.51764706,25.88125,-0.150245786,-0.546541834,0 +279,-89.30588235,25.88125,-0.037534689,-0.220120979,0 +280,-89.09411765,25.88125,-0.002611095,0.057836286,0 +281,-88.88235294,25.88125,0.02291235,0.168404335,0 +282,-88.67058824,25.88125,0.078929694,0.09678654,0 +283,-88.45882353,25.88125,0.146978722,0.152686076,0 +284,-88.24705882,25.88125,0.141612505,0.233362174,0 +285,-88.03529412,25.88125,0.16915561,0.208814065,0 +286,-87.82352941,25.88125,0.091689657,0.119051302,0 +287,-87.61176471,25.88125,0.146638228,0.155958491,0 +288,-87.4,25.88125,0.217603321,0.494927174,0 +289,-87.18823529,25.88125,0.23878443,-0.123333879,0 +290,-86.97647059,25.88125,0.194784911,-0.224739369,0 +291,-86.76470588,25.88125,0.251980448,-0.142474432,0 +292,-86.55294118,25.88125,0.391586736,-0.146894892,0 +293,-86.34117647,25.88125,0.407873416,-0.167468809,0 +294,-86.12941176,25.88125,0.468474617,-0.037905129,0 +295,-85.91764706,25.88125,0.449674371,-0.06903519,0 +296,-85.70588235,25.88125,0.360212995,-0.04202529,0 +297,-85.49411765,25.88125,0.268270971,-0.060195988,0 +298,-85.28235294,25.88125,0.13894377,-0.215928251,0 +299,-85.07058824,25.88125,0.084320653,-0.296736669,0 +300,-84.85882353,25.88125,0.116764238,-0.280460219,0 +301,-84.64705882,25.88125,0.013730035,-0.218459536,0 +302,-84.43529412,25.88125,-0.050889981,-0.105587868,0 +303,-84.22352941,25.88125,-0.019300266,-0.211886994,0 +304,-84.01176471,25.88125,0.019427973,-0.101704304,0 +305,-83.8,25.88125,0.031684577,-0.050969537,0 +306,-90.78823529,26.1125,0.039749266,-0.105871709,0 +307,-90.57647059,26.1125,0.010327879,-0.025544931,0 +308,-90.36470588,26.1125,-0.050688536,-0.127234109,0 +309,-90.15294118,26.1125,-0.092401096,-0.111699661,0 +310,-89.94117647,26.1125,-0.127450769,-0.234260364,0 +311,-89.72941176,26.1125,-0.093266615,-0.323968501,0 +312,-89.51764706,26.1125,-0.026599236,-0.509762616,0 +313,-89.30588235,26.1125,-0.005263159,-0.328953197,0 +314,-89.09411765,26.1125,0.052395798,0.013019942,0 +315,-88.88235294,26.1125,0.130517568,0.013353112,0 +316,-88.67058824,26.1125,0.141025843,0.143783343,0 +317,-88.45882353,26.1125,0.129038512,0.139305276,0 +318,-88.24705882,26.1125,0.210648567,0.343530606,0 +319,-88.03529412,26.1125,0.31663453,0.25560511,0 +320,-87.82352941,26.1125,0.245415092,0.143963519,0 +321,-87.61176471,26.1125,0.249265433,0.137448724,0 +322,-87.4,26.1125,0.332134225,0.23410559,0 +323,-87.18823529,26.1125,0.252730968,-0.150856718,0 +324,-86.97647059,26.1125,0.273283347,-0.21380526,0 +325,-86.76470588,26.1125,0.361644223,-0.243457819,0 +326,-86.55294118,26.1125,0.327327028,-0.192158909,0 +327,-86.34117647,26.1125,0.254002908,-0.0821479,0 +328,-86.12941176,26.1125,0.253089475,-0.009968208,0 +329,-85.91764706,26.1125,0.375831016,-0.066147891,0 +330,-85.70588235,26.1125,0.350098008,0.021628024,0 +331,-85.49411765,26.1125,0.330705502,-0.06842824,0 +332,-85.28235294,26.1125,0.187556477,0.035588136,0 +333,-85.07058824,26.1125,0.13715475,-0.180254345,0 +334,-84.85882353,26.1125,0.075806249,-0.127921871,0 +335,-84.64705882,26.1125,0.046370205,-0.118958648,0 +336,-84.43529412,26.1125,0.043288109,-0.254594504,0 +337,-84.22352941,26.1125,0.09574632,-0.30158871,0 +338,-84.01176471,26.1125,0.016568306,-0.107781119,0 +339,-83.8,26.1125,0.008828996,-0.091147237,0 +340,-90.78823529,26.34375,0.063502918,-0.116123223,0 +341,-90.57647059,26.34375,0.064182845,-0.024932155,0 +342,-90.36470588,26.34375,-0.016636174,-0.057556913,0 +343,-90.15294118,26.34375,-0.040705093,-0.113203941,0 +344,-89.94117647,26.34375,-0.01642502,-0.178565097,0 +345,-89.72941176,26.34375,-0.046116475,-0.328245069,0 +346,-89.51764706,26.34375,0.01373015,-0.435091742,0 +347,-89.30588235,26.34375,0.017788923,-0.225388643,0 +348,-89.09411765,26.34375,0.116123321,-0.010683381,0 +349,-88.88235294,26.34375,0.166419287,-0.049395028,0 +350,-88.67058824,26.34375,0.140347119,0.154749278,0 +351,-88.45882353,26.34375,0.196117444,0.098690536,0 +352,-88.24705882,26.34375,0.232865254,0.172522437,0 +353,-88.03529412,26.34375,0.382617258,0.207050693,0 +354,-87.82352941,26.34375,0.387904055,-0.089413643,0 +355,-87.61176471,26.34375,0.587562426,0.082745047,0 +356,-87.4,26.34375,0.487439097,0.09192189,0 +357,-87.18823529,26.34375,0.395320311,-0.07489581,0 +358,-86.97647059,26.34375,0.382626703,-0.207695305,0 +359,-86.76470588,26.34375,0.316409035,-0.114660594,0 +360,-86.55294118,26.34375,0.286911566,-0.100115912,0 +361,-86.34117647,26.34375,0.290432768,0.004263782,0 +362,-86.12941176,26.34375,0.379395858,0.024734445,0 +363,-85.91764706,26.34375,0.414484216,-0.077757217,0 +364,-85.70588235,26.34375,0.396400936,-0.052666671,0 +365,-85.49411765,26.34375,0.231168763,0.058377972,0 +366,-85.28235294,26.34375,0.083878426,0.071419445,0 +367,-85.07058824,26.34375,0.098906978,-0.06855577,0 +368,-84.85882353,26.34375,0.091478539,-0.111025639,0 +369,-84.64705882,26.34375,0.137048478,-0.183682377,0 +370,-84.43529412,26.34375,0.132850414,-0.222123323,0 +371,-84.22352941,26.34375,0.06581992,-0.16019666,0 +372,-84.01176471,26.34375,0.02986959,-0.094100613,0 +373,-83.8,26.34375,0.010203849,-0.063765137,0 +374,-90.78823529,26.575,0.114100825,-0.140868671,0 +375,-90.57647059,26.575,0.001893497,0.001049587,0 +376,-90.36470588,26.575,0.010214141,0.025098048,0 +377,-90.15294118,26.575,-0.045356443,-0.050229912,0 +378,-89.94117647,26.575,-0.083959465,-0.156061962,0 +379,-89.72941176,26.575,-0.075323043,-0.201721416,0 +380,-89.51764706,26.575,-0.140282147,-0.453087671,0 +381,-89.30588235,26.575,-0.079538885,-0.404974743,0 +382,-89.09411765,26.575,-0.007734609,-0.133299686,0 +383,-88.88235294,26.575,0.099508798,-0.001144728,0 +384,-88.67058824,26.575,0.173997699,0.130031045,0 +385,-88.45882353,26.575,0.141594529,0.144096641,0 +386,-88.24705882,26.575,0.141362382,0.145186239,0 +387,-88.03529412,26.575,0.23624143,-0.23097345,0 +388,-87.82352941,26.575,0.407392559,-0.25638763,0 +389,-87.61176471,26.575,0.444457146,-0.043794848,0 +390,-87.4,26.575,0.421860633,0.022664385,0 +391,-87.18823529,26.575,0.252514958,-0.076932475,0 +392,-86.97647059,26.575,0.269705859,0.008269503,0 +393,-86.76470588,26.575,0.263946814,-0.020907239,0 +394,-86.55294118,26.575,0.217665932,-0.014619679,0 +395,-86.34117647,26.575,0.231209801,-0.038629444,0 +396,-86.12941176,26.575,0.277662711,-0.059881691,0 +397,-85.91764706,26.575,0.391977347,-0.073687741,0 +398,-85.70588235,26.575,0.193642149,0.09105973,0 +399,-85.49411765,26.575,0.135910253,0.150897976,0 +400,-85.28235294,26.575,0.081446953,0.103790713,0 +401,-85.07058824,26.575,0.165006513,-0.121109339,0 +402,-84.85882353,26.575,0.163791573,-0.071855205,0 +403,-84.64705882,26.575,0.216144717,-0.114085579,0 +404,-84.43529412,26.575,0.083768764,-0.156322818,0 +405,-84.22352941,26.575,0.067137785,-0.125229948,0 +406,-84.01176471,26.575,0.06205672,-0.05864353,0 +407,-83.8,26.575,0.048044397,-0.036289716,0 +408,-90.78823529,26.80625,-0.009206026,-0.050935001,0 +409,-90.57647059,26.80625,0.026055447,-0.010874153,0 +410,-90.36470588,26.80625,-0.001108608,0.036281546,0 +411,-90.15294118,26.80625,-0.001050662,0.00439152,0 +412,-89.94117647,26.80625,-0.037619473,-0.070344741,0 +413,-89.72941176,26.80625,-0.087097055,-0.129746668,0 +414,-89.51764706,26.80625,-0.082289091,-0.269996553,0 +415,-89.30588235,26.80625,-0.085363696,-0.500188584,0 +416,-89.09411765,26.80625,-0.018274711,-0.130577036,0 +417,-88.88235294,26.80625,-0.021421122,-0.0899137,0 +418,-88.67058824,26.80625,0.004297595,0.020707884,0 +419,-88.45882353,26.80625,0.071961736,0.10102665,0 +420,-88.24705882,26.80625,0.189715962,0.015628441,0 +421,-88.03529412,26.80625,0.313407203,-0.429966774,0 +422,-87.82352941,26.80625,0.20808154,-0.31952313,0 +423,-87.61176471,26.80625,0.252774688,-0.037492143,0 +424,-87.4,26.80625,0.147496585,0.058163017,0 +425,-87.18823529,26.80625,0.170121949,0.01569084,0 +426,-86.97647059,26.80625,0.272868114,0.003129819,0 +427,-86.76470588,26.80625,0.27851665,-0.03039473,0 +428,-86.55294118,26.80625,0.271119123,-0.091433736,0 +429,-86.34117647,26.80625,0.263479147,0.001308847,0 +430,-86.12941176,26.80625,0.189635515,0.001629487,0 +431,-85.91764706,26.80625,0.138263813,0.096907934,0 +432,-85.70588235,26.80625,0.050204287,0.151982655,0 +433,-85.49411765,26.80625,0.001833714,0.131963933,0 +434,-85.28235294,26.80625,0.017255819,0.053812478,0 +435,-85.07058824,26.80625,0.037496557,-0.044073832,0 +436,-84.85882353,26.80625,-0.007741361,-0.027330843,0 +437,-84.64705882,26.80625,0.052290738,-0.085001008,0 +438,-84.43529412,26.80625,0.070679854,-0.130382583,0 +439,-84.22352941,26.80625,0.044335471,-0.115202346,0 +440,-84.01176471,26.80625,0.023617886,-0.084583804,0 +441,-83.8,26.80625,0.014888157,-0.004931356,0 +442,-90.78823529,27.0375,0.119735596,-0.027908129,0 +443,-90.57647059,27.0375,0.019012357,-0.010418724,0 +444,-90.36470588,27.0375,0.005771756,0.042381814,0 +445,-90.15294118,27.0375,0.072508656,-0.020801246,0 +446,-89.94117647,27.0375,0.003529583,-0.024540724,0 +447,-89.72941176,27.0375,-0.014284738,-0.064779797,0 +448,-89.51764706,27.0375,-0.085726174,-0.162728182,0 +449,-89.30588235,27.0375,-0.163826484,-0.344525195,0 +450,-89.09411765,27.0375,-0.131306376,-0.196937123,0 +451,-88.88235294,27.0375,-0.054112787,-0.082520064,0 +452,-88.67058824,27.0375,-0.006738036,-0.048383266,0 +453,-88.45882353,27.0375,0.034884064,0.005350065,0 +454,-88.24705882,27.0375,0.122567068,-0.23259505,0 +455,-88.03529412,27.0375,0.175343144,-0.349672502,0 +456,-87.82352941,27.0375,0.031526809,-0.191488806,0 +457,-87.61176471,27.0375,0.042913317,-0.065327721,0 +458,-87.4,27.0375,0.039532322,0.03352164,0 +459,-87.18823529,27.0375,0.061265657,0.036573636,0 +460,-86.97647059,27.0375,0.11005837,-0.01610953,0 +461,-86.76470588,27.0375,0.170889344,-0.045335206,0 +462,-86.55294118,27.0375,0.148511835,-0.062515589,0 +463,-86.34117647,27.0375,0.045981978,-0.0291828,0 +464,-86.12941176,27.0375,-0.006363569,0.072645683,0 +465,-85.91764706,27.0375,-0.004755505,0.126540385,0 +466,-85.70588235,27.0375,-0.030352055,0.162635541,0 +467,-85.49411765,27.0375,-0.033442149,0.068033475,0 +468,-85.28235294,27.0375,0.013397289,0.01471379,0 +469,-85.07058824,27.0375,-0.011773853,-0.043954178,0 +470,-84.85882353,27.0375,0.008114761,-0.083275202,0 +471,-84.64705882,27.0375,0.02212113,-0.106110721,0 +472,-84.43529412,27.0375,0.064227691,-0.162982284,0 +473,-84.22352941,27.0375,0.040482379,-0.077476388,0 +474,-84.01176471,27.0375,0.011693432,-0.050369363,0 +475,-83.8,27.0375,-0.030124658,-0.012615871,0 +476,-90.78823529,27.26875,0.030676165,0.030950887,0 +477,-90.57647059,27.26875,0.034760864,0.023963734,0 +478,-90.36470588,27.26875,0.080762348,-0.048696228,0 +479,-90.15294118,27.26875,0.095401189,-0.028853933,0 +480,-89.94117647,27.26875,0.103311465,-0.006305736,0 +481,-89.72941176,27.26875,0.023110392,-0.045348843,0 +482,-89.51764706,27.26875,-0.033797614,-0.117178948,0 +483,-89.30588235,27.26875,-0.159231807,-0.228988806,0 +484,-89.09411765,27.26875,-0.173692256,-0.30389746,0 +485,-88.88235294,27.26875,-0.08350019,-0.104022606,0 +486,-88.67058824,27.26875,-0.022797293,-0.100029245,0 +487,-88.45882353,27.26875,0.157769672,-0.129609877,0 +488,-88.24705882,27.26875,0.304537401,-0.263900284,0 +489,-88.03529412,27.26875,0.149645451,-0.173959182,0 +490,-87.82352941,27.26875,0.049181865,-0.100372279,0 +491,-87.61176471,27.26875,-0.00291244,-0.059133449,0 +492,-87.4,27.26875,-0.027489384,0.015601954,0 +493,-87.18823529,27.26875,0.010687838,0.025344381,0 +494,-86.97647059,27.26875,0.034256483,-0.020263794,0 +495,-86.76470588,27.26875,0.037501277,-0.064002724,0 +496,-86.55294118,27.26875,0.019713713,0.003952043,0 +497,-86.34117647,27.26875,-0.037105206,0.057188768,0 +498,-86.12941176,27.26875,-0.085127285,0.095261856,0 +499,-85.91764706,27.26875,-0.094035817,0.112604394,0 +500,-85.70588235,27.26875,-0.07303864,0.108054833,0 +501,-85.49411765,27.26875,-0.043985153,0.056258213,0 +502,-85.28235294,27.26875,-0.109166818,-0.005222569,0 +503,-85.07058824,27.26875,-0.032172276,-0.067639461,0 +504,-84.85882353,27.26875,0.026675478,-0.123010238,0 +505,-84.64705882,27.26875,0.050188383,-0.148461343,0 +506,-84.43529412,27.26875,0.051880923,-0.111808027,0 +507,-84.22352941,27.26875,0.028863826,-0.057332517,0 +508,-84.01176471,27.26875,-0.001427943,0.000908297,0 +509,-83.8,27.26875,-0.008136132,-0.020744734,0 +510,-90.78823529,27.5,0.034586975,-0.00517708,0 +511,-90.57647059,27.5,0.045215341,-0.057366413,0 +512,-90.36470588,27.5,0.071203049,-0.05184804,0 +513,-90.15294118,27.5,0.018589814,-0.051766273,0 +514,-89.94117647,27.5,0.031617283,-0.030409466,0 +515,-89.72941176,27.5,0.012284385,0.008082718,0 +516,-89.51764706,27.5,0.007553237,-0.011886523,0 +517,-89.30588235,27.5,-0.023118993,-0.109285054,0 +518,-89.09411765,27.5,-0.083566282,-0.214842918,0 +519,-88.88235294,27.5,-0.106612636,-0.186920593,0 +520,-88.67058824,27.5,0.072700665,-0.105248583,0 +521,-88.45882353,27.5,0.098090664,-0.122978414,0 +522,-88.24705882,27.5,0.041087497,-0.11927343,0 +523,-88.03529412,27.5,0.020582796,-0.121571589,0 +524,-87.82352941,27.5,-0.009243939,-0.141193291,0 +525,-87.61176471,27.5,-0.038827059,-0.021121758,0 +526,-87.4,27.5,-0.026887325,-0.008190579,0 +527,-87.18823529,27.5,-0.048391747,-0.003517729,0 +528,-86.97647059,27.5,-0.037227437,-0.049473375,0 +529,-86.76470588,27.5,-0.07773177,0.02807183,0 +530,-86.55294118,27.5,-0.14957728,0.080787088,0 +531,-86.34117647,27.5,-0.157985323,0.120579472,0 +532,-86.12941176,27.5,-0.139373904,0.10813917,0 +533,-85.91764706,27.5,-0.096610935,0.094576271,0 +534,-85.70588235,27.5,-0.084337462,0.073564149,0 +535,-85.49411765,27.5,-0.080913345,0.08207414,0 +536,-85.28235294,27.5,-0.026117701,-0.053440641,0 +537,-85.07058824,27.5,-0.008853652,-0.130690211,0 +538,-84.85882353,27.5,0.007536362,-0.098774007,0 +539,-84.64705882,27.5,0.017220944,-0.143542234,0 +540,-84.43529412,27.5,0.036156505,-0.140839446,0 +541,-84.22352941,27.5,0.01089513,0.000606245,0 +542,-84.01176471,27.5,0.006456676,-0.011532106,0 +543,-83.8,27.5,0.010180421,-0.005156976,0 \ No newline at end of file diff --git a/docs/examples/data/gulfdata_train.csv b/docs/examples/data/gulfdata_train.csv new file mode 100644 index 000000000..8c5475609 --- /dev/null +++ b/docs/examples/data/gulfdata_train.csv @@ -0,0 +1,21 @@ +,lon,lat,ubar,vbar +0,-90,26.5,0.017014439,-0.045338905 +1,-89.9353082,26.26236714,-0.027521352,-0.263696188 +2,-90.06139353,25.84260318,-0.151144052,-0.192281814 +3,-90.28714753,25.49465487,-0.149909671,-0.199497341 +4,-88.2,27,0.11553095,-0.181067045 +5,-87.90166407,26.67714267,0.384517986,-0.090623334 +6,-87.33337396,26.55351674,0.399623312,-0.18099943 +7,-86.76239529,26.33117253,0.414531666,-0.158313295 +8,-84.8,26,-0.044404483,-0.119692295 +9,-84.85842404,25.67073964,0.078196937,-0.374986066 +10,-84.84629796,25.05339588,0.04315034,-0.209116548 +11,-84.7794598,24.56733011,0.165777288,-0.334277532 +12,-86.1,24.8,-0.106249442,-0.282439498 +13,-86.3057102,24.47027326,-0.152320623,-0.108721538 +14,-86.55797559,24.33207825,-0.261465326,0.048502932 +15,-86.91782493,24.47417667,-0.278514359,0.023210374 +16,-89.2,25.1,-0.009065352,-0.065193047 +17,-89.17150107,24.88187548,0.087482163,-0.068463221 +18,-88.97508649,24.70856231,0.189755788,-0.051745985 +19,-88.6991099,24.68494422,0.02128361,0.07705565 \ No newline at end of file diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py new file mode 100644 index 000000000..d2bfad5c6 --- /dev/null +++ b/docs/examples/oceanmodelling.py @@ -0,0 +1,477 @@ +# %% [markdown] +# # Gaussian Processes for Vector Fields and Ocean Current Modelling +# +# In this notebook, we use Gaussian processes to learn vector valued functions. We will be +# recreating the results by [Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf) by an +# application to real world ocean surface velocity data, collected via surface drifters. +# +# Surface drifters are measurement devices that measure the dynamics and circulation patterns of the world's oceans. Studying and predicting ocean currents are important to climate research, for example forecasting and predicting oil spills, oceanographic surveying of eddies and upwelling, or providing information on the distribution of biomass in ecosystems. We will be using the [Gulf Drifters Open dataset](https://zenodo.org/record/4421585), which contains all publicly available surface drifter trajectories from the Gulf of Mexico spanning 28 years. +# %% +from jax.config import config + +config.update("jax_enable_x64", True) +from dataclasses import dataclass + +from jax import hessian +from jax.config import config +import jax.numpy as jnp +import jax.random as jr +from jaxtyping import ( + Array, + Float, + install_import_hook, +) +from matplotlib import rcParams +import matplotlib.pyplot as plt +import optax as ox +import pandas as pd +from sklearn.model_selection import train_test_split +import tensorflow_probability as tfp + +with install_import_hook("gpjax", "beartype.beartype"): + import gpjax as gpx + +# Enable Float64 for more stable matrix inversions. +key = jr.PRNGKey(123) +plt.style.use( + "https://raw.githubusercontent.com/JaxGaussianProcesses/GPJax/main/docs/examples/gpjax.mplstyle" +) +colors = rcParams["axes.prop_cycle"].by_key()["color"] + +import dataclasses +from gpjax import Constant +from gpjax.base import static_field + +# %% [markdown] +# ## Data Loading and problem setting +# The real dataset has been binned into an $N=34\times16$ grid, equally spaced over the longitude-latitude interval $[-90.8,-83.8] \times [24.0,27.5]$. Each bin has a size $\approx 0.21\times0.21$, and contains the average velocity across all measurements that fall inside it. +# +# We will call this binned ocean data the ground truth, and label it with the vector field +# $$ +# \mathbf{F} \equiv \mathbf{F}(\mathbf{x}), +# $$ +# where $\mathbf{x} = (x^{(0)}$,$x^{(1)})^\text{T}$, with a vector basis in the standard Cartesian directions (dimensions will be indicated by superscripts). +# +# We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_i$ is the 2 dimensional velocity vector at the $i$th location, $\mathbf{x}_i$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). +# + +# %% +#function to place data from csv into correct array shape +def prepare_data(df): + pos = jnp.array([df["lon"], df["lat"]]) + vel = jnp.array([df["ubar"], df["vbar"]]) + #extract shape stored as 'metadata' in the test data + try: + shape = (int(df["shape"][1]), int(df["shape"][0])) # shape = (34,16) + return pos, vel, shape + except KeyError: + return pos, vel + +# loading in data +try: + gulf_data_train = pd.read_csv("data/gulfdata_train.csv") + gulf_data_test = pd.read_csv("data/gulfdata_test.csv") +except FileNotFoundError: + gulf_data_train = pd.read_csv("docs/examples/data/gulfdata_train.csv") + gulf_data_test = pd.read_csv("docs/examples/data/gulfdata_test.csv") + + +pos_test, vel_test, shape = prepare_data(gulf_data_test) +pos_train, vel_train = prepare_data(gulf_data_train) + +fig, ax = plt.subplots(1, 1) +ax.quiver( + pos_test[0], pos_test[1], vel_test[0], vel_test[1], color=colors[0], label="$D_0$" +) +ax.quiver( + pos_train[0], + pos_train[1], + vel_train[0], + vel_train[1], + color=colors[1], + alpha=0.7, + label="$D_T$", +) +ax.legend() +plt.show() + +# %% [markdown] +# ## Problem Setting +# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth $D_0$. Note that $D_0$ is not passed into any functions used by GPJax, and is only used to compare against the two GP models at the end of the notebook. +# +# Since $\mathbf{F}$ is a vector-valued function, we require GPs that can directly learn vector-valued functions[1](#fn1). To implement this in GPJax, the problem can be changed to learn a scalar-valued function by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. +# +# For a particular measurement $\mathbf{y}$ (training or testing) at location $\mathbf{x}$, the components $(y^{(0)}, y^{(1)})$ are described by the latent vector field $\mathbf{F}$, such that +# +# $$ +# \mathbf{y} = \mathbf{F}(\mathbf{x}) = \left(\begin{array}{l} +# f^{(0)}\left(\mathbf{x}\right) \\ +# f^{(1)}\left(\mathbf{x}\right) +# \end{array}\right) +# $$ +# +# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. +# +# Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that +# +# $$ +# g \left(\mathbf{x} , 0 \right) = f^{(0)} ( \mathbf{x} ), \text{and } g \left( \mathbf{x}, 1 \right)=f^{(1)}\left(\mathbf{x}\right). +# $$ +# +# We have increased the input dimension by 1, from the 2D $\mathbf{x}$ to the 3D $\mathbf{X} = \left(\mathbf{x}, 0\right)$ or $\mathbf{X} = \left(\mathbf{x}, 1\right)$. +# +# By choosing the value of the third dimension, 0 or 1, we may now incorporate this information into computation of the kernel. +# We therefore make new 3D datasets $D_{T,3D} = \left\{\left( \mathbf{X}_{T,i},\mathbf{Y}_{T,i} \right) \right\} _{i=0}^{2N_T}$ and $D_{0,3D} = \left\{\left( \mathbf{X}_{0,i},\mathbf{Y}_{0,i} \right) \right\} _{i=0}^{2N}$ that incorporates this new labelling, such that for each dataset (indicated by the subscript $D = 0$ or $D=T$), +# +# $$ +# X_{D,i} = \left( \mathbf{x}_{D,i}, z \right), +# $$ +# and +# $$ +# Y_{D,i} = y_{D,i}^{(z)}, +# $$ +# +# where $z = 0$ if $i$ is odd and $z=1$ if $i$ is even. + +# %% +# Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) via the artificial z label +def label_position(data): + # introduce alternating z label + n_points = len(data[0]) + label = jnp.tile(jnp.array([0.0, 1.0]), n_points) + return jnp.vstack((jnp.repeat(data, repeats=2, axis=1), label)).T + +#change vectors y -> Y by reshaping the velocity measurements +def stack_velocity(data): + return data.T.flatten().reshape(-1, 1) + +pos_train3d = label_position(pos_train) +vel_train3d = stack_velocity(vel_train) + +# we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points +pos_test3d = label_position(pos_test) + +#place th etraining data into a Dataset object to be used by GPJax +DT = gpx.Dataset(X=pos_train3d, y=vel_train3d) + + +# %% [markdown] +# ## Velocity (Dimension) Decomposition +# Having labelled the data, we are now in a position to use GPJax to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly onto the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, +# +# $$ +# k_{\text{vel}} \left(\mathbf{X}, \mathbf{X}^{\prime}\right)= \begin{cases}k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right) & \text { if } z=z^{\prime} \\ 0 & \text { if } z \neq z^{\prime}\end{cases} +# $$ +# +# where $k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)$ are the user chosen kernels for each dimension. What this means is that there are no correlations between the $x^{(0)}$ and $x^{(1)}$ dimensions for all choices $\mathbf{X}$ and $\mathbf{X}^{\prime}$, since there are no off-diagonal elements in the Gram matrix populated by this choice. +# +# To implement this approach in GPJax, we define `velocity_kernel` in the following cell, following the steps outlined in the [custom kernels notebook](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels/#custom-kernel). This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. +# + +# %% +@dataclass +class velocity_kernel(gpx.kernels.AbstractKernel): + kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) + kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) + + def __call__( + self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] + ) -> Float[Array, "1"]: + # standard RBF-SE kernel is x and x' are on the same output, otherwise returns 0 + + z = jnp.array(X[2], dtype=int) + zp = jnp.array(Xp[2], dtype=int) + + #acheive the correct value via 'switches' that are either 1 or 0 + k0_switch = ((z + 1) % 2) * ((zp + 1) % 2) + k1_switch = z * zp + + return k0_switch * self.kernel0(X, Xp) + k1_switch * self.kernel1(X, Xp) + + +# %% [markdown] +# ### GPJax Implementation +# Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean and 0 observation noise. We choose a Gaussian marginal log likelihood (MLL). +# + +# %% +def initialise_gp(kernel, mean, dataset): + prior = gpx.Prior(mean_function=mean, kernel=kernel) + likelihood = gpx.Gaussian( + num_datapoints=dataset.n, obs_noise=jnp.array([1.0e-6], dtype=jnp.float64) + ) + posterior = prior * likelihood + return posterior + +# Define the velocity GP +mean = gpx.mean_functions.Zero() +kernel = velocity_kernel() +velocity_posterior = initialise_gp(kernel, mean, DT) + + +# %% [markdown] +# With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the marginal log likelihood using `optax`. We also plot its value at each step to visually confirm that we have found the minimum. See the [introduction to Gaussian Processes](https://docs.jaxgaussianprocesses.com/examples/intro_to_gps/) notebook for more information on optimising the MLL. + +# %% +def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): + # define the Marginal Log likelihood using DT + objective = gpx.objectives.ConjugateMLL(negative=True) + # Optimise to minimise the MLL + optimiser = ox.adam(learning_rate=0.1) + opt_posterior, history = gpx.fit( + model=posterior, + objective=objective, + train_data=dataset, + optim=optimiser, + num_iters=NIters, + safe=True, + key=key, + ) + #plot MLL value at each iteration + if plot_history: + fig, ax = plt.subplots(1, 1) + ax.plot(history, color=colors[1]) + ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") + + return opt_posterior + +opt_velocity_posterior = optimise_mll(velocity_posterior, DT) + + +# %% [markdown] +# ### Comparison +# We next obtain the latent distribution of the GP of $g$ at $\mathbf{x}_{0,i}$, then extract its mean and standard at the test locations, $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, as well as the standard deviation (we will use it at the very end). + +# %% +def latent_distribution(opt_posterior, pos_3d): + latent = opt_posterior.predict(pos_3d, train_data=DT) + latent_mean = latent.mean() + latent_std = latent.stddev() + return latent_mean, latent_std + + +# extract latent mean and std of g, redistribute into vectors to model F +velocity_mean, velocity_std = latent_distribution(opt_velocity_posterior, pos_test3d) + +vel_lat = [velocity_mean[::2], velocity_mean[1::2]] +pos_lat = pos_test + + +# %% [markdown] +# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $\mathbf{R}(\mathbf{x}_i) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) $, as well as $\left|\left|\mathbf{R}(\mathbf{x}_i)\right|\right|$. + +# %% +# Residuals between ground truth and estimate +def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape): + Y = pos_test[1] + X = pos_test[0] + # make figure + fig, ax = plt.subplots(1, 3, figsize=(12, 3)) + fig.tight_layout() + # ground truth + ax[0].quiver( + pos_test[0], + pos_test[1], + vel_test[0], + vel_test[1], + color=colors[0], + label="Training data", + scale = 10 + ) + ax[0].quiver( + pos_train[0], + pos_train[1], + vel_train[0], + vel_train[1], + color=colors[1], + label="Test Data", + scale = 10 + ) + ax[0].set( + xlim=[X.min() - 0.1, X.max() + 0.1], + ylim=[Y.min() + 0.1, Y.max() + 0.1], + aspect="equal", + title="Ground Truth", + ) + + # Latent estimate of vector field F + ax[1].quiver( + pos_lat[0], + pos_lat[1], + vel_lat[0], + vel_lat[1], + color=colors[3], + label="Latent estimate of Ground Truth", + scale = 10 + ) + ax[1].quiver( + pos_train[0], pos_train[1], vel_train[0], vel_train[1], color=colors[1] + ,scale = 10 + ) + ax[1].set( + xlim=[X.min() - 0.1, X.max() + 0.1], + ylim=[Y.min() + 0.1, Y.max() + 0.1], + aspect="equal", + title="GP Latent Estimate", + ) + + # residuals + residuals_vel = jnp.flip(jnp.sqrt((vel_test[0] - vel_lat[0]) ** 2 + + (vel_test[1] - vel_lat[1]) ** 2 + ).reshape(shape), axis = [0]) + im = ax[2].imshow( + residuals_vel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="winter") + + + ax[2].quiver(pos_test[0], pos_test[1],vel_lat[0] - vel_test[0], vel_lat[1] - vel_test[1] ,color = 'white', scale = 10) + ax[2].quiver( + pos_train[0], pos_train[1], vel_train[0], vel_train[1], color=colors[1] + ,scale = 10 + ) + ax[2].set( + xlim=[X.min() - 0.1, X.max() + 0.1], + ylim=[Y.min() + 0.1, Y.max() + 0.1], + aspect="equal", + title="Residuals", + ) + + fig.colorbar(im, fraction=0.027, pad=0.04, orientation="vertical", ) + plt.show() + + +plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape) + + +# %% [markdown] +# From the Latent Estimate we can see the velocity GP struggles to reconstruct features of the ground truth. This is because our construction of the kernel placed an independent prior on each physical dimension, which cannot be assumed. Therefore, we need a different approach that can implicitly incorporate this dependence at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. + +# %% [markdown] +# ## Helmholtz Decomposition +# In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)) such that +# $$ +# \mathbf{F}=\operatorname{grad} \Phi+\operatorname{rot} \Psi, +# $$ +# where +# $$ +# \operatorname{grad} \Phi:=\left[\begin{array}{l} +# \partial \Phi / \partial x^{(0)} \\ +# \partial \Phi / \partial x^{(1)} +# \end{array}\right] \text { and } \operatorname{rot} \Psi:=\left[\begin{array}{c} +# \partial \Psi / \partial x^{(1)} \\ +# -\partial \Psi / \partial x^{(0)} +# \end{array}\right]. +# $$ +# +# This is reminiscent of a 3 dimensional [Helmholtz decomposition](https://en.wikipedia.org/wiki/Helmholtz_decomposition). +# +# The 2 dimensional decomposition motivates a different approach: placing priors on $\Psi$ and $\Phi$, allowing us to make assumptions directly about fundamental properties of $\mathbf{F}$. If we choose independent GP priors such that $\Phi \sim \mathcal{G P}\left(0, k_{\Phi}\right)$ and $\Psi \sim \mathcal{G P}\left(0, k_{\Psi}\right)$, then $\mathbf{F} \sim \mathcal{G P} \left(0, k_\text{Helm}\right)$ (since acting linear operations on a GPs give GPs). +# +# For $\mathbf{X}, \mathbf{X}^{\prime} \in \mathbb{R}^2 \times \left\{0,1\right\}$ and $z, z^\prime \in \{0,1\}$, +# +# $$ +# \boxed{ k_{\mathrm{Helm}}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)_{z,z^\prime} = \frac{\partial^2 k_{\Phi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial\left(x^{\prime}\right)^{(z^\prime)}}+(-1)^{z+z^\prime} \frac{\partial^2 k_{\Psi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(1-z)} \partial\left(x^{\prime}\right)^{(1-z^\prime)}}}. +# $$ +# +# where $x^{(z)}$ and $(x^\prime)^{(z^\prime)}$ are the $z$ and $z^\prime$ components of $\mathbf{X}$ and ${\mathbf{X}}^{\prime}$ respectively. +# +# We compute the second derivatives using `jax.hessian`. In the following implementation, for a kernel $k(\mathbf{x}, \mathbf{x}^{\prime})$, this computes the Hessian matrix with respect to the components of $\mathbf{x}$ +# +# $$ +# \frac{\partial^2 k\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial x^{(z^\prime)}}. +# $$ +# +# Note that we have operated $\dfrac{\partial}{\partial x^{(z)}}$, *not* $\dfrac{\partial}{\partial \left(x^\prime \right)^{(z)}}$, as the boxed equation suggests. This is not an issue if we choose stationary kernels $k(\mathbf{x}, \mathbf{x}^{\prime}) = k(\mathbf{x} - \mathbf{x}^{\prime})$ , as the partial derivatives with respect to the components have the following exchange symmetry: +# +# $$ +# \frac{\partial}{\partial x^{(z)}} = - \frac{\partial}{\partial \left( x^\prime \right)^{(z)}} +# $$ +# +# for either $z$. +# %% +@dataclass +class helmholtz_kernel(gpx.kernels.AbstractKernel): + # initialise Phi and Psi kernels as any stationary kernel in gpJax + potential_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1,2]) + stream_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1,2]) + + def __call__( + self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] + ) -> Float[Array, "1"]: + + # obtain indices for k_helm, implement in the correct sign between the derivatives + z = jnp.array(X[2], dtype=int) + zp = jnp.array(Xp[2], dtype=int) + sign = (-1) ** (z + zp) + + # convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) + potential_dvtve = -jnp.array( + hessian(self.potential_kernel)(X, Xp), dtype=jnp.float64 + )[z][zp] + stream_dvtve = -jnp.array( + hessian(self.stream_kernel)(X, Xp), dtype=jnp.float64 + )[1-z][1-zp] + + return potential_dvtve + sign * stream_dvtve + + +# %% [markdown] +# ### GPJax Implementation +# We repeat the exact same steps as with the velocity GP model, but replacing `velocity_kernel` with `helmholtz_kernel`. + +# %% +# Redefine Gaussian process with Helmholtz kernel +kernel = helmholtz_kernel() +helmholtz_posterior = initialise_gp(kernel, mean, DT) +# Optimise hyperparameters using optax +opt_helmholtz_posterior = optimise_mll(helmholtz_posterior, DT) + + +# %% [markdown] +# ### Comparison +# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i)$ and $\left|\left|R(\mathbf{x}_i) \right|\right|$. + +# %% +# obtain latent distribution, extract x and y values over g +helmholtz_mean, helmholtz_std = latent_distribution(opt_helmholtz_posterior, pos_test3d) +vel_lat = [helmholtz_mean[::2], helmholtz_mean[1::2]] +pos_lat = pos_test + +plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape) + +# %% [markdown] +# Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). + + +# %% [markdown] +# ## Negative Log Predictive Densities +# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data. +# +# $$ +# \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right), +# $$ +# +# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. + +# %% +# ensure testing data alternates between x0 and x1 components +def nlpd(mean, std, vel_test): + vel_query = jnp.column_stack((vel_test[0], vel_test[1])).flatten() + normal = tfp.substrates.jax.distributions.Normal(loc=mean, scale=std) + return -jnp.sum(normal.log_prob(vel_query)) + +#compute nlpd for velocity and helmholtz +nlpd_vel = nlpd(velocity_mean, velocity_std, vel_test) +nlpd_helm = nlpd(helmholtz_mean, helmholtz_std, vel_test) + +print("NLPD for Velocity: %.2f \nNLPD for Helmholtz: %.2f" % (nlpd_vel, nlpd_helm)) +# %% [markdown] +# The Helmholtz model outperforms the velocity model, as indicated by the lower NLPD score. + +# %% [markdown] +# +# ## Footnote +# Kernels for vector valued functions have been studied in the literature, see [Alvarez et. al, (2012)](https://doi.org/10.48550/arXiv.1106.6251) +# ## System Configuration +# %% +# %reload_ext watermark +# %watermark -n -u -v -iv -w -a 'Ivan Shalashilin' diff --git a/docs/examples/vectorfields.py b/docs/examples/vectorfields.py deleted file mode 100644 index 89e40a674..000000000 --- a/docs/examples/vectorfields.py +++ /dev/null @@ -1,493 +0,0 @@ -# %% [markdown] -# # Gaussian Processes for Vector Fields -# In this notebook, we use Gaussian processes to learn vector valued functions. We will be -# recreating the results by [Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf). -# %% -from jax.config import config - -config.update("jax_enable_x64", True) -import torch - -torch.manual_seed(123) -import jax.random as jr -import jax.numpy as jnp -from jaxtyping import install_import_hook -import matplotlib.pyplot as plt -from matplotlib import rcParams -from mpl_toolkits.axes_grid1 import make_axes_locatable -import numpy as onp -import optax as ox -import tensorflow_probability as tfp -from jax.config import config -from dataclasses import dataclass -from jaxtyping import ( - Array, - Float, - install_import_hook, -) -from jax import hessian, jit - -with install_import_hook("gpjax", "beartype.beartype"): - import gpjax as gpx - -# Enable Float64 for more stable matrix inversions. -key = jr.PRNGKey(123) -plt.style.use( - "https://raw.githubusercontent.com/JaxGaussianProcesses/GPJax/main/docs/examples/gpjax.mplstyle" -) -cols = rcParams["axes.prop_cycle"].by_key()["color"] - -# jnp.set_printoptions(4, edgeitems=30, linewidth=100000, -# formatter=dict(float=lambda x: "%.3g" % x)) - - -# %% [markdown] -# ## Data Loading -# Data and original code are publicly available at https://github.com/renatoberlinghieri/Helmholtz-GP -# -# The data are 297 (artificial) measurements of ocean velocity, given by the vector field -# -# $$ -# \mathbf{F}(\mathbf{x}) = -x^{(1)}\hat{\imath} + x^{(0)}\hat{\jmath}, -# $$ -# -# -# -# where $\mathbf{x} = (x^{(0)}$,$x^{(1)})^\text{T}$, $\hat{\imath}$ and $\hat{\jmath}$ are unit vectors in the standard Cartesian directions (dimensions will be indicated by superscripts). -# -# The measurements are contained in a dataset $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_i$ is a 2 dimensional velocity vector and $\mathbf{x}_i$ is a 2 dimensional position vector on an $N=17\times17$ grid, equally spaced over the interval $[-1,1] \times[-1,1]$. 8 measurements of $\mathbf{F}(\mathbf{x})$ at new locations are contained in a dataset $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^8$, which are allocated to training data. -# -# - -# %% -# loading in data -try: - Pos_Train = onp.genfromtxt("data/XY_train_vortex.csv", delimiter=",").T - Pos_Test = onp.genfromtxt("data/XY_test_vortex.csv", delimiter=",").T - Vel_Train = onp.genfromtxt("data/UV_train_vortex.csv", delimiter=",").T - Vel_Test = onp.genfromtxt("data/UV_test_vortex.csv", delimiter=",").T -except FileNotFoundError: - Pos_Train = onp.genfromtxt( - "docs/examples/data/XY_train_vortex.csv", delimiter="," - ).T - Pos_Test = onp.genfromtxt("docs/examples/data/XY_test_vortex.csv", delimiter=",").T - Vel_Train = onp.genfromtxt( - "docs/examples/data/UV_train_vortex.csv", delimiter="," - ).T - Vel_Test = onp.genfromtxt("docs/examples/data/UV_test_vortex.csv", delimiter=",").T - - -fig, ax = plt.subplots(1, 1) -ax.quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="$D_0$") -ax.quiver( - Pos_Train[0], - Pos_Train[1], - Vel_Train[0], - Vel_Train[1], - color="red", - alpha=0.7, - label="$D_T$", -) -ax.set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal") -ax.legend() -plt.show() - -# %% [markdown] -# ## Problem Setting -# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth ($D_0$). Note that the model only sees $D_T$, and $D_0$ is used in the final benchmark only. -# -# Since $\mathbf{F}$ is a vector-valued function, we would ideally require GPs that can learn vector-valued functions. Currently, GPJax only supports learning scalar-valued functions' GPs[1](#fn1) . However, since $D_T$ contains a 2D vector measurement $\mathbf{y}_{T,i}$ at each location $\mathbf{x}_{T,i}$, we may get around this by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. -# -# For a particular $\mathbf{y}$ (training or testing) at location $\mathbf{x}$, the components $(y^{(0)}, y^{(1)})$ are described by the latent vector field $\mathbf{F}$ such that -# -# $$ -# \mathbf{y} = \mathbf{F}(\mathbf{x}) = \left(\begin{array}{l} -# f^{(0)}\left(\mathbf{x}\right) \\ -# f^{(1)}\left(\mathbf{x}\right) -# \end{array}\right) -# $$ -# -# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that -# -# $$ -# g \left(\mathbf{x} , 0 \right) = f^{(0)} ( \mathbf{x} ), \text{and } g \left( \mathbf{x}, 1 \right)=f^{(1)}\left(\mathbf{x}\right). -# $$ -# -# We have increased the input dimension by 1, from the 2D $\mathbf{x}$ to 3D $\left(\mathbf{x}, 0\right)$ or $\left(\mathbf{x}, 1\right)$ -# -# By choosing the value of the third dimension, 0 or 1, we may now incorporate this information into computation of the kernel. -# We therefore make new 3D datasets $D_{T,3D} = \left\{\left( \mathbf{X}_{T,i},\mathbf{Y}_{T,i} \right) \right\} _{i=0}^{16}$ and $D_{0,3D} = \left\{\left( \mathbf{X}_{0,i},\mathbf{Y}_{0,i} \right) \right\} _{i=0}^{2N}$ that incorporates this new labelling, such that for each dataset (indicated by the subscript $D = 0$ or $D=T$), -# -# $$ -# X_{D,i} = \left( \mathbf{x}_{D,i}, z \right), -# $$ -# and -# $$ -# Y_{D,i} = y_{D,i}^{(z)}, -# $$ -# -# where $z = 0$ if $i$ is odd and $z=1$ if $i$ is even. - -# %% - -# introduce alternating z label -NTrain = len(Pos_Train[0]) -NTest = len(Pos_Test[0]) -zLabelTrain = jnp.tile(jnp.array([0.0, 1.0]), NTrain) -zLabelTest = jnp.tile(jnp.array([0.0, 1.0]), NTest) -# Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) using via the artificial z label -PosTrain3D = jnp.vstack((jnp.repeat(Pos_Train, repeats=2, axis=1), zLabelTrain)).T -VelTrain3D = Vel_Train.T.flatten().reshape(-1, 1) -# we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points -PosTest3D = jnp.vstack( - (jnp.repeat(Pos_Test.reshape(2, 289), repeats=2, axis=1), zLabelTest) -).T -# Pass the labelled training data into gpx.dataset object -D0 = gpx.Dataset(X=PosTrain3D, y=VelTrain3D) - -# %% [markdown] -# ## Velocity (Dimension) Decomposition -# Having labelled the data, we are now in a position to use a GP to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly onto the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, -# -# $$ -# k_{\text{vel}} \left(\mathbf{X}, \mathbf{X}^{\prime}\right)= \begin{cases}k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right) & \text { if } z=z^{\prime} \\ 0 & \text { if } z \neq z^{\prime}\end{cases} -# $$ -# -# where $k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)$ are the user are kernels for each dimension. What this means is that there are no correlations between the $x^{(0)}$ and $x^{(1)}$ dimensions for all choices $\mathbf{X}$ and $\mathbf{X}^{\prime}$, since there are no off-diagonal elements in the Gram matrix populated by this choice. -# -# To implement this approach in GPJax, we define `VelocityKernel` in the following cell, following the steps outlined in the creating new kernels notebook. This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. -# - -# %% -from jax.numpy import exp - - -@dataclass -class VelocityKernel(gpx.kernels.AbstractKernel): - kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) - kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) - - def __call__( - self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] - ) -> Float[Array, "1"]: - # standard RBF-SE kernel is x and x' are on the same output, otherwise returns 0. acheive the correct value via 'Switches' - - z = X[2] - zp = Xp[2] - - k0Switch = (z + 1) % 2 * (zp + 1) % 2 - k1Switch = z * zp - - return k0Switch * self.kernel0(X, Xp) + k1Switch * self.kernel1(X, Xp) - - -# %% [markdown] -# ### GPJax Implementation -# Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean. We choose a Gaussian likelihood. -# - -# %% -# Define the Helmholtz GP -kernel = VelocityKernel() -mean = gpx.mean_functions.Zero() -Prior = gpx.Prior(mean_function=mean, kernel=kernel) -Likelihood = gpx.Gaussian( - num_datapoints=D0.n, obs_noise=jnp.array([1.0], dtype=jnp.float64) -) -Posterior = Prior * Likelihood - - -# %% [markdown] -# With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the marginal log likelihood using `optax`. We also plot its value at each step to visually confirm that we have found the minimum - -# %% - -# define the Marginal Log likelihood using D0 -Objective = gpx.objectives.ConjugateMLL(negative=True) -Objective(Posterior, train_data=D0) -Optimiser = ox.adam(learning_rate=0.01) -Objective = jit(Objective) - -NIters = 10000 -# Optimise to minimise the MLL -OptPosteriorVel, history = gpx.fit( - model=Posterior, - objective=Objective, - train_data=D0, - optim=Optimiser, - num_iters=NIters, - safe=True, - key=key, -) - -fig, ax = plt.subplots(1, 1) -ax.plot(history, color="red") -ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") -plt.show() - -# %% [markdown] -# ### Comparison -# We next obtain the latent distribution of the GP of $g$ at $\mathbf{x}_{0,i}$, then extract its mean and standard at the test locations, $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, as well as the standard deviation (we will use it at the very end). - -# %% -VelocityLatent = OptPosteriorVel.predict(PosTest3D, train_data=D0) -VelocityMean = VelocityLatent.mean() -VelocityStd = VelocityLatent.stddev() -# extract x0 and x1 values over g -Vel_Lat = [VelocityMean[::2].reshape(17, 17), VelocityMean[1::2].reshape(17, 17)] -Pos_Lat = Pos_Test - -# %% [markdown] -# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. - -# %% - -# Residuals between ground truth and estimate -ResidualsVel = jnp.sqrt( - (Vel_Test[0].reshape(17, 17) - Vel_Lat[0]) ** 2 - + (Vel_Test[1].reshape(17, 17) - Vel_Lat[1]) ** 2 -) -X = Pos_Test[0] -Y = Pos_Test[1] - -# make figure -fig, ax = plt.subplots(1, 3) -fig.tight_layout() -# ground truth -ax[0].quiver( - Pos_Train[0], - Pos_Train[1], - Vel_Train[0], - Vel_Train[1], - color="red", - label="Testing Data", -) -ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="Training data") -ax[0].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Ground Truth") - -# Latent estimate of vector field F -ax[1].quiver( - Pos_Lat[0], - Pos_Lat[1], - Vel_Lat[0], - Vel_Lat[1], - color="darkblue", - label="Latent estimate of $\mathbf{F}$", -) -ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color="red") -ax[1].set( - xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="GP Latent Estimate" -) - -im = ax[2].imshow(ResidualsVel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="hot") -ax[2].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Residuals") -fig.colorbar(im, fraction=0.046, pad=0.04, orientation="vertical") -plt.show() - -# %% [markdown] -# From the residuals it is evident the GP does not perform well far from the training data. This is because our construction of the kernel placed an independent prior on each physical dimension. This is incorrect, as by definition $f^{(z)}$ is directly proportional to $x^{(z^\prime)}$ for both physical dimensions. Therefore, we need a different approach that can implicitly incorporate this at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. - -# %% [markdown] -# ## Helmholtz Decomposition -# In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)): -# $$ -# \mathbf{F}=\operatorname{grad} \Phi+\operatorname{rot} \Psi -# $$ -# where -# $$ -# \operatorname{grad} \Phi:=\left[\begin{array}{l} -# \partial \Phi / \partial x^{(0)} \\ -# \partial \Phi / \partial x^{(1)} -# \end{array}\right] \text { and } \operatorname{rot} \Psi:=\left[\begin{array}{c} -# \partial \Psi / \partial x^{(1)} \\ -# -\partial \Psi / \partial x^{(0)} -# \end{array}\right] -# $$ -# -# This is reminiscent of a 3 dimensional [Helmholtz decomposition](https://en.wikipedia.org/wiki/Helmholtz_decomposition). -# -# The 2 dimensional decomposition motivates a different approach: placing priors on $\Psi$ and $\Phi$, allowing us to make assumptions directly about fundamental properties of $\mathbf{F}$. If we choose independent GP priors such that $\Phi \sim \mathcal{G P}\left(0, k_{\Phi}\right)$ and $\Psi \sim \mathcal{G P}\left(0, k_{\Psi}\right)$, then $\mathbf{F} \sim \mathcal{G P} \left(0, k_\text{Helm}\right)$ (since acting linear operations on a GPs give GPs). -# -# For $\mathbf{X}, \mathbf{X}^{\prime} \in \mathbb{R}^2 \times \left\{0,1\right\}$ and $z, z^\prime \in \{0,1\}$, -# -# $$ -# \boxed{ k_{\mathrm{Helm}}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)_{z,z^\prime} = \frac{\partial^2 k_{\Phi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial\left(x^{\prime}\right)^{(z^\prime)}}+(-1)^{z+z^\prime} \frac{\partial^2 k_{\Psi}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(1-z)} \partial\left(x^{\prime}\right)^{(1-z^\prime)}}}. -# $$ -# -# where $x^{(z)}$ and $(x^\prime)^{(z^\prime)}$ are the $z$ and $z^\prime$ components of $\mathbf{X}$ and ${\mathbf{X}}^{\prime}$ respectively. -# -# We compute the second derivatives using `jax.hessian`. In the following implementation, for a kernel $k(\mathbf{x}, \mathbf{x}^{\prime})$, this computes the Hessian matrix with respect to the components of $\mathbf{x}$ -# -# $$ -# \frac{\partial^2 k\left(\mathbf{x}, \mathbf{x}^{\prime}\right)}{\partial x^{(z)} \partial x^{(z^\prime)}}. -# $$ -# -# Note that we have operated $\dfrac{\partial}{\partial x^{(z)}}$, *not* $\dfrac{\partial}{\partial \left(x^\prime \right)^{(z)}}$, as the boxed equation suggests. This is not an issue if we choose stationary kernels $k(\mathbf{x}, \mathbf{x}^{\prime}) = k(\mathbf{x} - \mathbf{x}^{\prime})$ , as the partial derivatives with respect to the components have the following exchange symmetry: -# -# $$ -# \frac{\partial}{\partial x^{(z)}} = - \frac{\partial}{\partial \left( x^\prime \right)^{(z)}} -# $$ -# -# for either $z$. We specify that this implementation only works with stationary kernels by setting the type of `kernelPhi` and `kernelPsi` to `gpx.kernels.stationary`. -# %% - - -@dataclass -class HelmholtzKernel(gpx.kernels.AbstractKernel): - # initialise Phi and Psi kernels as any stationary kernel in gpJax - kernelPhi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims=[0, 1]) - kernelPsi: gpx.kernels.stationary = gpx.kernels.RBF(active_dims=[0, 1]) - - def __call__( - self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] - ) -> Float[Array, "1"]: - # obtain indices for k_helm, implement in the correct sign between the derivatives - z = jnp.array(X[2], dtype=int) - zp = jnp.array(Xp[2], dtype=int) - Sign = (-1) ** (z + zp) - # convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) - DivPhi = -jnp.array(hessian(self.kernelPhi)(X, Xp), dtype=jnp.float64)[z][zp] - DivPsi = -jnp.array(hessian(self.kernelPsi)(X, Xp), dtype=jnp.float64)[1 - z][ - 1 - zp - ] - - return DivPhi + Sign * DivPsi - - -# %% [markdown] -# ### GPJax Implementation -# We repeat the exact same steps as with the velocity GP model, but replacing `VelocityKernel` with `HelmholtzKernel`. - -# %% -# Redefine Gaussian process with Helmholtz kernel -kernel = HelmholtzKernel() -Prior = gpx.Prior(mean_function=mean, kernel=kernel) -Likelihood = gpx.Gaussian( - num_datapoints=D0.n, obs_noise=jnp.array([1.0], dtype=jnp.float64) -) -Posterior = Prior * Likelihood - -# Optimise hyperparameters using optax -Objective = gpx.objectives.ConjugateMLL(negative=True) -Objective(Posterior, train_data=D0) -Optimiser = ox.adam(learning_rate=0.01) -Objective = jit(Objective) - -OptPosteriorHelm, history = gpx.fit( - model=Posterior, - objective=Objective, - train_data=D0, - optim=Optimiser, - num_iters=NIters, - safe=True, - key=key, -) - -fig, ax = plt.subplots(1, 1) -ax.plot(history, color="red") -ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") -plt.show() - -# extract the mean -HelmholtzLatent = OptPosteriorHelm.predict(PosTest3D, train_data=D0) -HelmholtzMean = HelmholtzLatent.mean() -HelmholtzStd = HelmholtzLatent.stddev() -# extract x and y values over g -Helm_Lat = [HelmholtzMean[::2].reshape(17, 17), HelmholtzMean[1::2].reshape(17, 17)] -Pos_Lat = Pos_Test - -# %% [markdown] -# ### Comparison -# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \left|\left| \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) \right|\right|$. - -# %% - -# Residuals between ground truth and estimate -ResidualsHelm = jnp.sqrt( - (Vel_Test[0].reshape(17, 17) - Helm_Lat[0]) ** 2 - + (Vel_Test[1].reshape(17, 17) - Helm_Lat[1]) ** 2 -) -X = Pos_Test[0] -Y = Pos_Test[1] - -# make figure -fig, ax = plt.subplots(1, 3) -fig.tight_layout() -# ground truth -ax[0].quiver( - Pos_Train[0], - Pos_Train[1], - Vel_Train[0], - Vel_Train[1], - color="red", - label="Testing Data", -) -ax[0].quiver(Pos_Test[0], Pos_Test[1], Vel_Test[0], Vel_Test[1], label="Training data") -ax[0].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Ground Truth") -# Latent estimate of vector field F -ax[1].quiver( - Pos_Lat[0], - Pos_Lat[1], - Helm_Lat[0], - Helm_Lat[1], - color="darkblue", - label="Latent estimate of $\mathbf{F}$", -) -ax[1].quiver(Pos_Train[0], Pos_Train[1], Vel_Train[0], Vel_Train[1], color="red") -ax[1].set( - xlim=[-1.3, 1.3], - ylim=[-1.3, 1.3], - aspect="equal", - title="GP Latent Estimate of $\mathbf{F}$", -) -# Residuals -im = ax[2].imshow( - ResidualsHelm, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="hot" -) -ax[2].set(xlim=[-1.3, 1.3], ylim=[-1.3, 1.3], aspect="equal", title="Residuals") -fig.colorbar(im, fraction=0.046, pad=0.04, orientation="vertical") -plt.show() - -# %% [markdown] -# Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$, supportd by the residuals being much smaller than with the velocity decomposition. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). - - -# %% [markdown] -# ## Negative Log Predictive Densities -# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data, -# -# $$ -# \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right) -# $$ -# -# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. - -# %% -# ensure testing data alternates between x0 and x1 components -Vel_Query = jnp.column_stack((Vel_Test[0], Vel_Test[1])).flatten() - -NormalVel = tfp.substrates.jax.distributions.Normal( - loc=VelocityMean, - scale=VelocityStd, -) -NormalHelm = tfp.substrates.jax.distributions.Normal( - loc=HelmholtzMean, - scale=HelmholtzStd, -) - -NLPDVel = -jnp.sum(NormalVel.log_prob(Vel_Query)) -NLPDHelm = -jnp.sum(NormalHelm.log_prob(Vel_Query)) - -print("NLPD for Velocity: %.2f \nNLPD for Helmholtz: %.2f" % (NLPDVel, NLPDHelm)) -# %% [markdown] -# The Helmholtz model significantly outperforms the velocity model, as indicated by the lower NLPD score. - - -# %% [markdown] -# -# ## Footnote -# Kernels for vector valued functions have been studied in the literature, see [Alvarez et. al, (2012)](https://doi.org/10.48550/arXiv.1106.6251) -# ## System Configuration -# %% -# %reload_ext watermark -# %watermark -n -u -v -iv -w -a 'Ivan Shalashilin' From 0c1f1d95a2b8e8eea77ed71c3ceb435bee231335 Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Thu, 24 Aug 2023 15:02:13 +0100 Subject: [PATCH 29/76] small fix to active dims of kernels --- docs/examples/oceanmodelling.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index d2bfad5c6..c4ce081c8 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -391,8 +391,8 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap @dataclass class helmholtz_kernel(gpx.kernels.AbstractKernel): # initialise Phi and Psi kernels as any stationary kernel in gpJax - potential_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1,2]) - stream_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1,2]) + potential_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1]) + stream_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1]) def __call__( self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] From a062fd0ca2705a0ccb12d0af8d58decab53bea3c Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Thu, 24 Aug 2023 15:12:36 +0100 Subject: [PATCH 30/76] formatting --- docs/examples/data/gulfdata_test.csv | 2 +- docs/examples/data/gulfdata_train.csv | 2 +- docs/examples/oceanmodelling.py | 103 +++++++++++++++++--------- 3 files changed, 72 insertions(+), 35 deletions(-) diff --git a/docs/examples/data/gulfdata_test.csv b/docs/examples/data/gulfdata_test.csv index 313c4793a..6d2517826 100644 --- a/docs/examples/data/gulfdata_test.csv +++ b/docs/examples/data/gulfdata_test.csv @@ -542,4 +542,4 @@ 540,-84.43529412,27.5,0.036156505,-0.140839446,0 541,-84.22352941,27.5,0.01089513,0.000606245,0 542,-84.01176471,27.5,0.006456676,-0.011532106,0 -543,-83.8,27.5,0.010180421,-0.005156976,0 \ No newline at end of file +543,-83.8,27.5,0.010180421,-0.005156976,0 diff --git a/docs/examples/data/gulfdata_train.csv b/docs/examples/data/gulfdata_train.csv index 8c5475609..7cdc4dc34 100644 --- a/docs/examples/data/gulfdata_train.csv +++ b/docs/examples/data/gulfdata_train.csv @@ -18,4 +18,4 @@ 16,-89.2,25.1,-0.009065352,-0.065193047 17,-89.17150107,24.88187548,0.087482163,-0.068463221 18,-88.97508649,24.70856231,0.189755788,-0.051745985 -19,-88.6991099,24.68494422,0.02128361,0.07705565 \ No newline at end of file +19,-88.6991099,24.68494422,0.02128361,0.07705565 diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index c4ce081c8..16744a568 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -55,18 +55,20 @@ # We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_i$ is the 2 dimensional velocity vector at the $i$th location, $\mathbf{x}_i$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). # + # %% -#function to place data from csv into correct array shape +# function to place data from csv into correct array shape def prepare_data(df): pos = jnp.array([df["lon"], df["lat"]]) vel = jnp.array([df["ubar"], df["vbar"]]) - #extract shape stored as 'metadata' in the test data + # extract shape stored as 'metadata' in the test data try: shape = (int(df["shape"][1]), int(df["shape"][0])) # shape = (34,16) return pos, vel, shape except KeyError: return pos, vel + # loading in data try: gulf_data_train = pd.read_csv("data/gulfdata_train.csv") @@ -77,7 +79,7 @@ def prepare_data(df): pos_test, vel_test, shape = prepare_data(gulf_data_test) -pos_train, vel_train = prepare_data(gulf_data_train) +pos_train, vel_train = prepare_data(gulf_data_train) fig, ax = plt.subplots(1, 1) ax.quiver( @@ -110,7 +112,7 @@ def prepare_data(df): # \end{array}\right) # $$ # -# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. +# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. # # Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that # @@ -133,6 +135,7 @@ def prepare_data(df): # # where $z = 0$ if $i$ is odd and $z=1$ if $i$ is even. + # %% # Change vectors x -> X = (x,z), and vectors y -> Y = (y,z) via the artificial z label def label_position(data): @@ -141,17 +144,19 @@ def label_position(data): label = jnp.tile(jnp.array([0.0, 1.0]), n_points) return jnp.vstack((jnp.repeat(data, repeats=2, axis=1), label)).T -#change vectors y -> Y by reshaping the velocity measurements + +# change vectors y -> Y by reshaping the velocity measurements def stack_velocity(data): return data.T.flatten().reshape(-1, 1) + pos_train3d = label_position(pos_train) vel_train3d = stack_velocity(vel_train) # we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points pos_test3d = label_position(pos_test) -#place th etraining data into a Dataset object to be used by GPJax +# place th etraining data into a Dataset object to be used by GPJax DT = gpx.Dataset(X=pos_train3d, y=vel_train3d) @@ -168,6 +173,7 @@ def stack_velocity(data): # To implement this approach in GPJax, we define `velocity_kernel` in the following cell, following the steps outlined in the [custom kernels notebook](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels/#custom-kernel). This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. # + # %% @dataclass class velocity_kernel(gpx.kernels.AbstractKernel): @@ -181,8 +187,8 @@ def __call__( z = jnp.array(X[2], dtype=int) zp = jnp.array(Xp[2], dtype=int) - - #acheive the correct value via 'switches' that are either 1 or 0 + + # achieve the correct value via 'switches' that are either 1 or 0 k0_switch = ((z + 1) % 2) * ((zp + 1) % 2) k1_switch = z * zp @@ -194,6 +200,7 @@ def __call__( # Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean and 0 observation noise. We choose a Gaussian marginal log likelihood (MLL). # + # %% def initialise_gp(kernel, mean, dataset): prior = gpx.Prior(mean_function=mean, kernel=kernel) @@ -203,6 +210,7 @@ def initialise_gp(kernel, mean, dataset): posterior = prior * likelihood return posterior + # Define the velocity GP mean = gpx.mean_functions.Zero() kernel = velocity_kernel() @@ -212,6 +220,7 @@ def initialise_gp(kernel, mean, dataset): # %% [markdown] # With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the marginal log likelihood using `optax`. We also plot its value at each step to visually confirm that we have found the minimum. See the [introduction to Gaussian Processes](https://docs.jaxgaussianprocesses.com/examples/intro_to_gps/) notebook for more information on optimising the MLL. + # %% def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): # define the Marginal Log likelihood using DT @@ -227,7 +236,7 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): safe=True, key=key, ) - #plot MLL value at each iteration + # plot MLL value at each iteration if plot_history: fig, ax = plt.subplots(1, 1) ax.plot(history, color=colors[1]) @@ -235,6 +244,7 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): return opt_posterior + opt_velocity_posterior = optimise_mll(velocity_posterior, DT) @@ -242,6 +252,7 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): # ### Comparison # We next obtain the latent distribution of the GP of $g$ at $\mathbf{x}_{0,i}$, then extract its mean and standard at the test locations, $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, as well as the standard deviation (we will use it at the very end). + # %% def latent_distribution(opt_posterior, pos_3d): latent = opt_posterior.predict(pos_3d, train_data=DT) @@ -260,6 +271,7 @@ def latent_distribution(opt_posterior, pos_3d): # %% [markdown] # We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $\mathbf{R}(\mathbf{x}_i) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) $, as well as $\left|\left|\mathbf{R}(\mathbf{x}_i)\right|\right|$. + # %% # Residuals between ground truth and estimate def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape): @@ -276,7 +288,7 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap vel_test[1], color=colors[0], label="Training data", - scale = 10 + scale=10, ) ax[0].quiver( pos_train[0], @@ -285,7 +297,7 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap vel_train[1], color=colors[1], label="Test Data", - scale = 10 + scale=10, ) ax[0].set( xlim=[X.min() - 0.1, X.max() + 0.1], @@ -302,11 +314,15 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap vel_lat[1], color=colors[3], label="Latent estimate of Ground Truth", - scale = 10 + scale=10, ) ax[1].quiver( - pos_train[0], pos_train[1], vel_train[0], vel_train[1], color=colors[1] - ,scale = 10 + pos_train[0], + pos_train[1], + vel_train[0], + vel_train[1], + color=colors[1], + scale=10, ) ax[1].set( xlim=[X.min() - 0.1, X.max() + 0.1], @@ -314,19 +330,33 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap aspect="equal", title="GP Latent Estimate", ) - + # residuals - residuals_vel = jnp.flip(jnp.sqrt((vel_test[0] - vel_lat[0]) ** 2 - + (vel_test[1] - vel_lat[1]) ** 2 - ).reshape(shape), axis = [0]) + residuals_vel = jnp.flip( + jnp.sqrt( + (vel_test[0] - vel_lat[0]) ** 2 + (vel_test[1] - vel_lat[1]) ** 2 + ).reshape(shape), + axis=[0], + ) im = ax[2].imshow( - residuals_vel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="winter") - - - ax[2].quiver(pos_test[0], pos_test[1],vel_lat[0] - vel_test[0], vel_lat[1] - vel_test[1] ,color = 'white', scale = 10) + residuals_vel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="winter" + ) + ax[2].quiver( - pos_train[0], pos_train[1], vel_train[0], vel_train[1], color=colors[1] - ,scale = 10 + pos_test[0], + pos_test[1], + vel_lat[0] - vel_test[0], + vel_lat[1] - vel_test[1], + color="white", + scale=10, + ) + ax[2].quiver( + pos_train[0], + pos_train[1], + vel_train[0], + vel_train[1], + color=colors[1], + scale=10, ) ax[2].set( xlim=[X.min() - 0.1, X.max() + 0.1], @@ -334,8 +364,13 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap aspect="equal", title="Residuals", ) - - fig.colorbar(im, fraction=0.027, pad=0.04, orientation="vertical", ) + + fig.colorbar( + im, + fraction=0.027, + pad=0.04, + orientation="vertical", + ) plt.show() @@ -345,6 +380,7 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap # %% [markdown] # From the Latent Estimate we can see the velocity GP struggles to reconstruct features of the ground truth. This is because our construction of the kernel placed an independent prior on each physical dimension, which cannot be assumed. Therefore, we need a different approach that can implicitly incorporate this dependence at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. + # %% [markdown] # ## Helmholtz Decomposition # In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)) such that @@ -391,25 +427,24 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap @dataclass class helmholtz_kernel(gpx.kernels.AbstractKernel): # initialise Phi and Psi kernels as any stationary kernel in gpJax - potential_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1]) - stream_kernel:gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0,1]) + potential_kernel: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) + stream_kernel: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) def __call__( self, X: Float[Array, "1 D"], Xp: Float[Array, "1 D"] ) -> Float[Array, "1"]: - - # obtain indices for k_helm, implement in the correct sign between the derivatives + # obtain indices for k_helm, implement in the correct sign between the derivatives z = jnp.array(X[2], dtype=int) zp = jnp.array(Xp[2], dtype=int) sign = (-1) ** (z + zp) - + # convert to array to correctly index, -ve sign due to exchange symmetry (only true for stationary kernels) potential_dvtve = -jnp.array( hessian(self.potential_kernel)(X, Xp), dtype=jnp.float64 )[z][zp] stream_dvtve = -jnp.array( hessian(self.stream_kernel)(X, Xp), dtype=jnp.float64 - )[1-z][1-zp] + )[1 - z][1 - zp] return potential_dvtve + sign * stream_dvtve @@ -452,6 +487,7 @@ def __call__( # # where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. + # %% # ensure testing data alternates between x0 and x1 components def nlpd(mean, std, vel_test): @@ -459,7 +495,8 @@ def nlpd(mean, std, vel_test): normal = tfp.substrates.jax.distributions.Normal(loc=mean, scale=std) return -jnp.sum(normal.log_prob(vel_query)) -#compute nlpd for velocity and helmholtz + +# compute nlpd for velocity and helmholtz nlpd_vel = nlpd(velocity_mean, velocity_std, vel_test) nlpd_helm = nlpd(helmholtz_mean, helmholtz_std, vel_test) From 4b19843b63730bec50a143f45006a82eff0f8497 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 25 Aug 2023 14:02:49 +0100 Subject: [PATCH 31/76] Add logic for running a decision making loop Added an `AbstractDecisionMaker` abstract base class which can be implemented in order to define a decision making loop. A concrete implementation, in the form of a `DecisionMaker` class, has been added. At its heart it has two core methods: 1. `ask` which is used to get a point to be queried next. 2. `tell` which is used to tell the `DecisionMaker` about new observations. In a typical decision making setup this will result in the datsets and posteriors being updated. In addition to this, in the `DecisionMaker` a `run` method is provided, which will automatically run the decision making loop for n steps. After the `ask` step, the functions in the `post_ask` list will be executed, taking as arguments the decision maker and the point chosen to be queried next. Similarly, after the `tell` step, the functions in the `post_tell` list are executed, taking the decision maker as the sole argument. --- gpjax/decision_making/__init__.py | 8 + gpjax/decision_making/decision_maker.py | 254 ++++++++++++++ gpjax/decision_making/utils.py | 35 +- pyproject.toml | 2 - .../test_decision_maker.py | 330 ++++++++++++++++++ tests/test_decision_making/test_utils.py | 46 +++ tests/test_decision_making/utils.py | 45 +++ 7 files changed, 717 insertions(+), 3 deletions(-) create mode 100644 gpjax/decision_making/decision_maker.py create mode 100644 tests/test_decision_making/test_decision_maker.py create mode 100644 tests/test_decision_making/test_utils.py create mode 100644 tests/test_decision_making/utils.py diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index c3ff92262..50c7d551b 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -21,6 +21,10 @@ AbstractAcquisitionMaximizer, ContinuousAcquisitionMaximizer, ) +from gpjax.decision_making.decision_maker import ( + AbstractDecisionMaker, + DecisionMaker, +) from gpjax.decision_making.posterior_handler import PosteriorHandler from gpjax.decision_making.search_space import ( AbstractSearchSpace, @@ -32,14 +36,18 @@ LogarithmicGoldsteinPrice, Quadratic, ) +from gpjax.decision_making.utils import build_function_evaluator __all__ = [ "AbstractAcquisitionFunctionBuilder", "AbstractAcquisitionMaximizer", + "AbstractDecisionMaker", "AbstractSearchSpace", "AcquisitionFunction", + "build_function_evaluator", "ContinuousAcquisitionMaximizer", "ContinuousSearchSpace", + "DecisionMaker", "AbstractContinuousTestFunction", "Forrester", "LogarithmicGoldsteinPrice", diff --git a/gpjax/decision_making/decision_maker.py b/gpjax/decision_making/decision_maker.py new file mode 100644 index 000000000..ddfff18b0 --- /dev/null +++ b/gpjax/decision_making/decision_maker.py @@ -0,0 +1,254 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from abc import ( + ABC, + abstractmethod, +) +from dataclasses import ( + dataclass, + field, +) + +from beartype.typing import ( + Callable, + Dict, + List, + Mapping, +) +import jax.random as jr + +from gpjax.dataset import Dataset +from gpjax.decision_making.acquisition_functions import ( + AbstractAcquisitionFunctionBuilder, +) +from gpjax.decision_making.acquisition_maximizer import AbstractAcquisitionMaximizer +from gpjax.decision_making.posterior_handler import PosteriorHandler +from gpjax.decision_making.search_space import AbstractSearchSpace +from gpjax.decision_making.utils import FunctionEvaluator +from gpjax.gps import AbstractPosterior +from gpjax.typing import ( + Array, + Float, + KeyArray, +) + + +@dataclass +class AbstractDecisionMaker(ABC): + """ + AbstractDecisionMaker abstract base class which handles the core decision loop. The + decision making loop is split into two key steps, `ask` and `tell`. The `ask` + step is typically used to decide which point to query next. The `tell` step is + typically used to update models and datasets with newly queried points. + + Attributes: + search_space (AbstractSearchSpace): Search space which is being queried + posterior_handlers (Dict[str, PosteriorHandler]): Dictionary of posterior + handlers, which are used to update posteriors throughout the decision making + loop. Tags are used to distinguish between posteriors. In a typical Bayesian + optimisation setup one of the tags will be `OBJECTIVE`, defined in + decision_making.utils. + datasets (Dict[str, Dataset]): Dictionary of datasets, which are augmented with + observations throughout the decision making loop. In a typical setup they are + also used to fit the posteriors, using the `posterior_handlers`. Tags are used + to distinguish datasets, and correspond to tags in `posterior_handlers`. + acquisition_function_builder (AbstractAcquisitionFunctionBuilder): Object which + builds acquisition functions from posteriors and datasets, to decide where + to query next. In a typical Bayesian optimisation setup the point chosen to + be queried next is the point which maximizes the acquisition function. + acquisition_maximizer (AbstractAcquisitionMaximizer): Object which maximizes + acquisition functions over the search space. + key (KeyArray): JAX random key, used to generate random numbers. + post_ask (List[Callable]): List of functions to be executed after each ask step. + post_tell (List[Callable]): List of functions to be executed after each tell + step. + """ + + search_space: AbstractSearchSpace + posterior_handlers: Dict[str, PosteriorHandler] + datasets: Dict[str, Dataset] + acquisition_function_builder: AbstractAcquisitionFunctionBuilder + acquisition_maximizer: AbstractAcquisitionMaximizer + key: KeyArray + post_ask: List[Callable] = field( + default_factory=list + ) # Specific type is List[Callable[[DecisionMaker, Float[Array, ["1 D"]]], None]] but causes Beartype issues + post_tell: List[Callable] = field( + default_factory=list + ) # Specific type is List[Callable[[DecisionMaker], None]] but causes Beartype issues + + @abstractmethod + def ask(self, key: KeyArray) -> Float[Array, "1 D"]: + """ + In a typical decision making setup this will use the + `acquisition_function_builder` to form an acquisition function and then return + the point which maximizes the acquisition function using the + `acquisition_maximizer` as the point to be queried next. + + Args: + key (KeyArray): JAX PRNG key for controlling random state. + + Returns: + Float[Array, "1 D"]: Point to be queried next + """ + raise NotImplementedError + + @abstractmethod + def tell(self, observation_datasets: Mapping[str, Dataset], key: KeyArray): + """ + Tell decision maker about new observations. In a typical decision making setup + we will update the datasets and posteriors with the new observations. + + Args: + observation_datasets (Mapping[str, Dataset]): Dictionary of datasets + containing new observations. Tags are used to distinguish datasets, and + correspond to tags in `posterior_handlers` in a typical setup. + key (KeyArray): JAX PRNG key for controlling random state. + """ + raise NotImplementedError + + +@dataclass +class DecisionMaker(AbstractDecisionMaker): + """ + DecisionMaker class which handles the core decision making loop in a typical setup. The + decision making loop is split into two key steps, `ask` and `tell`. The `ask` + step forms an `AcquisitionFunction` from the current `posteriors` and `datasets` and + returns the point which maximises it. It also stores the formed acquisition function + under the attribute `self.current_acquisition_function` so that it can be called, + for instance for plotting, after the `ask` function has been called. The `tell` step + adds a newly queried point to the `datasets` and updates the `posteriors`. + + This can be run as a typical ask-tell loop, or the `run` method can be used to run + the decision making loop for a fixed number of steps. Moreover, the `run` method executes + the functions in `post_ask` and `post_tell` after each ask and tell step + respectively. This enables the user to add custom functionality, such as the ability + to plot values of interest during the optimization process. + """ + + def __post_init__(self): + """ + At initialisation we check that the posterior handlers and datasets are + consistent (i.e. have the same tags), and then initialise the posteriors, optimizing them using the + corresponding datasets. + """ + # Check that posterior handlers and datasets are consistent + if self.posterior_handlers.keys() != self.datasets.keys(): + raise ValueError( + "Posterior handlers and datasets must have the same keys. " + f"Got posterior handlers keys {self.posterior_handlers.keys()} and " + f"datasets keys {self.datasets.keys()}." + ) + + # Initialize posteriors + self.posteriors: Dict[str, AbstractPosterior] = {} + for tag, posterior_handler in self.posterior_handlers.items(): + self.posteriors[tag] = posterior_handler.get_posterior( + self.datasets[tag], optimize=True, key=self.key + ) + + def ask(self, key: KeyArray) -> Float[Array, "1 D"]: + """ + Get updated acquisition function and return the point which maximises it. This + method also stores the acquisition function in + `self.current_acquisition_function` so that it can be accessed after the ask + function has been called. This is useful for non-deterministic acquisition + functions, which will differ between calls to `ask` due to the splitting of + `self.key`. + + Args: + key (KeyArray): JAX PRNG key for controlling random state. + + Returns: + Float[Array, "1 D"]: Point to be queried next. + """ + self.current_acquisition_function = ( + self.acquisition_function_builder.build_acquisition_function( + self.posteriors, self.datasets, key + ) + ) + + key, _ = jr.split(key) + return self.acquisition_maximizer.maximize( + self.current_acquisition_function, self.search_space, key + ) + + def tell(self, observation_datasets: Mapping[str, Dataset], key: KeyArray): + """ + Add newly observed data to datasets and update the corresponding posteriors. + + Args: + observation_datasets (Mapping[str, Dataset]): Dictionary of datasets + containing new observations. Tags are used to distinguish datasets, and + correspond to tags in `posterior_handlers` and `self.datasets`. + key (KeyArray): JAX PRNG key for controlling random state. + """ + if observation_datasets.keys() != self.datasets.keys(): + raise ValueError( + "Observation datasets and existing datasets must have the same keys. " + f"Got observation datasets keys {observation_datasets.keys()} and " + f"existing datasets keys {self.datasets.keys()}." + ) + + for tag, observation_dataset in observation_datasets.items(): + self.datasets[tag] += observation_dataset + + for tag, posterior_handler in self.posterior_handlers.items(): + key, _ = jr.split(key) + self.posteriors[tag] = posterior_handler.update_posterior( + self.datasets[tag], self.posteriors[tag], optimize=True, key=key + ) + + def run( + self, n_steps: int, black_box_function_evaluator: FunctionEvaluator + ) -> Mapping[str, Dataset]: + """ + Run the decision making loop continuously for for `n_steps`. This is broken down + into three main steps: + 1. Call the `ask` method to get the point to be queried next. + 2. Call the `black_box_function_evaluator` to evaluate the black box functions + of interest at the point chosen to be queried. + 3. Call the `tell` method to update the datasets and posteriors with the newly + observed data. + + In addition to this, after the `ask` step, the functions in the `post_ask` list + are executed, taking as arguments the decision maker and the point chosen to be + queried next. Similarly, after the `tell` step, the functions in the `post_tell` + list are executed, taking the decision maker as the sole argument. + + Args: + n_steps (int): Number of steps to run the decision making loop for. + black_box_function_evaluator (FunctionEvaluator): Function evaluator which + evaluates the black box functions of interest at supplied points. + + Returns: + Mapping[str, Dataset]: Dictionary of datasets containing the observations + made throughout the decision making loop, as well as the initial data + supplied when initialising the `DecisionMaker`. + """ + for _ in range(n_steps): + query_point = self.ask(self.key) + + for post_ask_method in self.post_ask: + post_ask_method(self, query_point) + + self.key, _ = jr.split(self.key) + observation_datasets = black_box_function_evaluator(query_point) + self.tell(observation_datasets, self.key) + + for post_tell_method in self.post_tell: + post_tell_method(self) + + return self.datasets diff --git a/gpjax/decision_making/utils.py b/gpjax/decision_making/utils.py index 91fa9a924..55087c172 100644 --- a/gpjax/decision_making/utils.py +++ b/gpjax/decision_making/utils.py @@ -12,6 +12,39 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from beartype.typing import Final +from beartype.typing import ( + Callable, + Dict, + Final, +) + +from gpjax.dataset import Dataset +from gpjax.typing import ( + Array, + Float, +) OBJECTIVE: Final[str] = "OBJECTIVE" +""" +Tag for the objective dataset/function in standard acquisition functions. +""" + + +FunctionEvaluator = Callable[[Float[Array, "N D"]], Dict[str, Dataset]] +""" +Type alias for function evaluators, which take an array of points of shape $`[N, D]`$ +and evaluate a set of functions at each point, returning a mapping from function tags +to datasets of the evaluated points. This is the same as the `Observer` in Trieste: +https://github.com/secondmind-labs/trieste/blob/develop/trieste/observer.py +""" + + +def build_function_evaluator( + functions: Dict[str, Callable[[Float[Array, "N D"]], Float[Array, "N 1"]]] +) -> FunctionEvaluator: + """ + Takes a dictionary of functions and returns a `FunctionEvaluator` which can be + used to evaluate each of the functions at a supplied set of points and return a + dictionary of datasets storing the evaluated points. + """ + return lambda x: {tag: Dataset(x, f(x)) for tag, f in functions.items()} diff --git a/pyproject.toml b/pyproject.toml index a20ecb254..b673e198f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -133,8 +133,6 @@ select = [ "TID", # implicit string concatenation "ISC", - # type-checking imports - "TCH", ] ignore = [ # space before : (needed for how black formats slicing) diff --git a/tests/test_decision_making/test_decision_maker.py b/tests/test_decision_making/test_decision_maker.py new file mode 100644 index 000000000..235b5bc35 --- /dev/null +++ b/tests/test_decision_making/test_decision_maker.py @@ -0,0 +1,330 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax import config + +config.update("jax_enable_x64", True) + +import jax.numpy as jnp +import jax.random as jr +import optax as ox +import pytest + +import gpjax as gpx +from gpjax.dataset import Dataset +from gpjax.decision_making.acquisition_functions import ( + AbstractAcquisitionFunctionBuilder, +) +from gpjax.decision_making.acquisition_maximizer import ( + AbstractAcquisitionMaximizer, + ContinuousAcquisitionMaximizer, +) +from gpjax.decision_making.decision_maker import ( + AbstractDecisionMaker, + DecisionMaker, +) +from gpjax.decision_making.posterior_handler import PosteriorHandler +from gpjax.decision_making.search_space import ( + AbstractSearchSpace, + ContinuousSearchSpace, +) +from gpjax.decision_making.test_functions import Quadratic +from gpjax.decision_making.utils import ( + OBJECTIVE, + build_function_evaluator, +) +from gpjax.typing import KeyArray +from tests.test_decision_making.utils import QuadraticAcquisitionFunctionBuilder + +CONSTRAINT = "CONSTRAINT" + + +@pytest.fixture +def search_space() -> ContinuousSearchSpace: + return ContinuousSearchSpace( + lower_bounds=jnp.array([0.0], dtype=jnp.float64), + upper_bounds=jnp.array([1.0], dtype=jnp.float64), + ) + + +@pytest.fixture +def posterior_handler() -> PosteriorHandler: + mean = gpx.Zero() + kernel = gpx.Matern52(lengthscale=jnp.array(1.0), variance=jnp.array(1.0)) + prior = gpx.Prior(mean_function=mean, kernel=kernel) + likelihood_builder = lambda x: gpx.Gaussian( + num_datapoints=x, obs_noise=jnp.array(1e-6) + ) + posterior_handler = PosteriorHandler( + prior=prior, + likelihood_builder=likelihood_builder, + optimization_objective=gpx.ConjugateMLL(negative=True), + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=100, + ) + return posterior_handler + + +@pytest.fixture +def acquisition_function_builder() -> AbstractAcquisitionFunctionBuilder: + return QuadraticAcquisitionFunctionBuilder() + + +@pytest.fixture +def acquisition_maximizer() -> AbstractAcquisitionMaximizer: + return ContinuousAcquisitionMaximizer(num_initial_samples=1000, num_restarts=1) + + +def get_dataset(num_points: int, key: KeyArray) -> Dataset: + test_function = Quadratic() + dataset = test_function.generate_dataset(num_points=num_points, key=key) + return dataset + + +def test_abstract_decision_maker_raises_error(): + with pytest.raises(TypeError): + AbstractDecisionMaker() + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_invalid_tags_raises_error( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = {"CONSTRAINT": dataset} # Dataset tag doesn't match posterior tag + with pytest.raises(ValueError): + DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_initialisation_optimizes_posterior_hyperparameters( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} + objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + constraint_dataset = get_dataset(num_points=5, key=jr.PRNGKey(10)) + datasets = {"OBJECTIVE": objective_dataset, CONSTRAINT: constraint_dataset} + decision_maker = DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + # Assert kernel hyperparameters get changed from their initial values + assert decision_maker.posteriors[OBJECTIVE].prior.kernel.lengthscale != jnp.array( + 1.0 + ) + assert decision_maker.posteriors[OBJECTIVE].prior.kernel.variance != jnp.array(1.0) + assert decision_maker.posteriors[CONSTRAINT].prior.kernel.lengthscale != jnp.array( + 1.0 + ) + assert decision_maker.posteriors[CONSTRAINT].prior.kernel.variance != jnp.array(1.0) + assert ( + decision_maker.posteriors[CONSTRAINT].prior.kernel.lengthscale + != decision_maker.posteriors[OBJECTIVE].prior.kernel.lengthscale + ) + assert ( + decision_maker.posteriors[CONSTRAINT].prior.kernel.variance + != decision_maker.posteriors[OBJECTIVE].prior.kernel.variance + ) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_ask( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = {"OBJECTIVE": objective_dataset} + decision_maker = DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + initial_decision_maker_key = decision_maker.key + query_point = decision_maker.ask(key=key) + assert query_point.shape == (1, 1) + assert jnp.allclose(query_point, jnp.array([[0.5]]), atol=1e-5) + assert decision_maker.current_acquisition_function is not None + assert ( + decision_maker.key == initial_decision_maker_key + ).all() # Ensure decision maker key is unchanged + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_tell_with_inconsistent_observations_raises_error( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} + initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + initial_constraint_dataset = get_dataset(num_points=5, key=jr.PRNGKey(10)) + datasets = { + "OBJECTIVE": initial_objective_dataset, + CONSTRAINT: initial_constraint_dataset, + } + decision_maker = DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + mock_objective_observation = get_dataset(num_points=1, key=jr.PRNGKey(1)) + mock_constraint_observation = get_dataset(num_points=1, key=jr.PRNGKey(2)) + observations = { + OBJECTIVE: mock_objective_observation, + "CONSTRAINT_ONE": mock_constraint_observation, # Deliberately incorrect tag + } + with pytest.raises(ValueError): + decision_maker.tell(observation_datasets=observations, key=key) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_tell_updates_datasets_and_models( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} + initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + initial_constraint_dataset = get_dataset(num_points=5, key=jr.PRNGKey(10)) + datasets = { + "OBJECTIVE": initial_objective_dataset, + CONSTRAINT: initial_constraint_dataset, + } + decision_maker = DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + initial_decision_maker_key = decision_maker.key + initial_objective_posterior = decision_maker.posteriors[OBJECTIVE] + initial_constraint_posterior = decision_maker.posteriors[CONSTRAINT] + mock_objective_observation = get_dataset(num_points=1, key=jr.PRNGKey(1)) + mock_constraint_observation = get_dataset(num_points=1, key=jr.PRNGKey(2)) + observations = { + OBJECTIVE: mock_objective_observation, + CONSTRAINT: mock_constraint_observation, + } + decision_maker.tell(observation_datasets=observations, key=key) + assert decision_maker.datasets[OBJECTIVE].n == 6 + assert decision_maker.datasets[CONSTRAINT].n == 6 + assert decision_maker.datasets[OBJECTIVE].X[-1] == mock_objective_observation.X[0] + assert decision_maker.datasets[CONSTRAINT].X[-1] == mock_constraint_observation.X[0] + assert ( + decision_maker.posteriors[OBJECTIVE].prior.kernel.lengthscale + != initial_objective_posterior.prior.kernel.lengthscale + ) + assert ( + decision_maker.posteriors[OBJECTIVE].prior.kernel.variance + != initial_objective_posterior.prior.kernel.variance + ) + assert ( + decision_maker.posteriors[CONSTRAINT].prior.kernel.lengthscale + != initial_constraint_posterior.prior.kernel.lengthscale + ) + assert ( + decision_maker.posteriors[CONSTRAINT].prior.kernel.variance + != initial_constraint_posterior.prior.kernel.variance + ) + assert ( + decision_maker.key == initial_decision_maker_key + ).all() # Ensure decision maker key has not been updated + + +@pytest.mark.parametrize("n_steps", [1, 3]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_run( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + acquisition_function_builder: AbstractAcquisitionFunctionBuilder, + acquisition_maximizer: AbstractAcquisitionMaximizer, + n_steps: int, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = { + "OBJECTIVE": initial_objective_dataset, + } + decision_maker = DecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + acquisition_function_builder=acquisition_function_builder, + acquisition_maximizer=acquisition_maximizer, + key=key, + ) + initial_decision_maker_key = decision_maker.key + black_box_fn = Quadratic() + black_box_function_evaluator = build_function_evaluator( + {OBJECTIVE: black_box_fn.evaluate} + ) + query_datasets = decision_maker.run( + n_steps=n_steps, black_box_function_evaluator=black_box_function_evaluator + ) + assert query_datasets[OBJECTIVE].n == 5 + n_steps + assert ( + jnp.abs(query_datasets[OBJECTIVE].X[-n_steps:] - jnp.array([[0.5]])) < 1e-5 + ).all() # Ensure we're querying the correct point in our dummy acquisition function at each step + assert ( + decision_maker.key != initial_decision_maker_key + ).all() # Ensure decision maker key gets updated diff --git a/tests/test_decision_making/test_utils.py b/tests/test_decision_making/test_utils.py new file mode 100644 index 000000000..f77bc6cab --- /dev/null +++ b/tests/test_decision_making/test_utils.py @@ -0,0 +1,46 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +from jax import config + +config.update("jax_enable_x64", True) + +import jax.numpy as jnp + +from gpjax.decision_making.utils import ( + OBJECTIVE, + build_function_evaluator, +) +from gpjax.typing import ( + Array, + Float, +) + + +def test_build_function_evaluator(): + def _square(x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: + return x**2 + + def _cube(x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: + return x**3 + + functions = {OBJECTIVE: _square, "CONSTRAINT": _cube} + fn_evaluator = build_function_evaluator(functions) + x = jnp.array([[2.0, 3.0]]) + datasets = fn_evaluator(x) + assert datasets.keys() == functions.keys() + assert jnp.equal(datasets[OBJECTIVE].X, x).all() + assert jnp.equal(datasets[OBJECTIVE].y, _square(x)).all() + assert jnp.equal(datasets["CONSTRAINT"].X, x).all() + assert jnp.equal(datasets["CONSTRAINT"].y, _cube(x)).all() diff --git a/tests/test_decision_making/utils.py b/tests/test_decision_making/utils.py new file mode 100644 index 000000000..f92b793d8 --- /dev/null +++ b/tests/test_decision_making/utils.py @@ -0,0 +1,45 @@ +# Copyright 2023 The JaxGaussianProcesses Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +from beartype.typing import Mapping + +from gpjax.dataset import Dataset +from gpjax.decision_making.acquisition_functions import ( + AbstractAcquisitionFunctionBuilder, + AcquisitionFunction, +) +from gpjax.decision_making.test_functions import Quadratic +from gpjax.gps import ConjugatePosterior +from gpjax.typing import KeyArray + + +class QuadraticAcquisitionFunctionBuilder(AbstractAcquisitionFunctionBuilder): + """ + Dummy acquisition function builder for testing purposes, which returns the negative + of the value of a quadratic test function at the input points. This is because + acquisition functions are *maximised*, and we wish to *minimise* the quadratic test + function. + """ + + def build_acquisition_function( + self, + posteriors: Mapping[str, ConjugatePosterior], + datasets: Mapping[str, Dataset], + key: KeyArray, + ) -> AcquisitionFunction: + test_function = Quadratic() + return lambda x: -1.0 * test_function.evaluate( + x + ) # Acquisition functions are *maximised* From fe8bde413bb7af9bf95764ac8f5e3c1c43cb2fcb Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 25 Aug 2023 14:22:28 +0100 Subject: [PATCH 32/76] Fix failing test --- tests/test_mean_functions.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/test_mean_functions.py b/tests/test_mean_functions.py index 105e3a629..d4a660c39 100644 --- a/tests/test_mean_functions.py +++ b/tests/test_mean_functions.py @@ -1,11 +1,10 @@ # Enable Float64 for more stable matrix inversions. -from jax.config import config +from jax import config config.update("jax_enable_x64", True) import jax -from jax import jit import jax.numpy as jnp import jax.random as jr from jaxtyping import ( @@ -72,10 +71,7 @@ def test_zero_mean_remains_zero() -> None: posterior = prior * likelihood negative_mll = gpx.objectives.ConjugateMLL(negative=True) - negative_mll(posterior, train_data=D) - negative_mll = jit(negative_mll) - - opt_posterior, history = gpx.fit( + opt_posterior, _ = gpx.fit( model=posterior, objective=negative_mll, train_data=D, From 7c858913854fb9370d8be252e0cb8c5e4b2da41a Mon Sep 17 00:00:00 2001 From: Francesco Zanetta <62377868+frazane@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:25:23 +0200 Subject: [PATCH 33/76] Support for missing values using masked dataset (#340) * add mask field to dataset * tests for masked dataset * invert mask * dummy shape kwarg * masked log prob and posterior prediction * avoid recomputing mask in batched fit * improve dataset initialization * fix dataset static typing * fix docstring * refactor mask computation * add log_prob test * Change sentinel class to string literal * Make ruff happy * trigger github actions --------- Co-authored-by: Ingmar Schuster --- gpjax/dataset.py | 47 ++++++++++++++++++++++++--- gpjax/fit.py | 4 +-- gpjax/gaussian_distribution.py | 19 +++++++++-- gpjax/gps.py | 14 +++++++- gpjax/linops/dense_linear_operator.py | 4 ++- gpjax/objectives.py | 4 ++- tests/test_dataset.py | 44 +++++++++++++++++++++++-- tests/test_gaussian_distribution.py | 21 ++++++++++++ 8 files changed, 141 insertions(+), 16 deletions(-) diff --git a/gpjax/dataset.py b/gpjax/dataset.py index d2364b281..3fc99325e 100644 --- a/gpjax/dataset.py +++ b/gpjax/dataset.py @@ -16,9 +16,16 @@ from dataclasses import dataclass import warnings -from beartype.typing import Optional +from beartype.typing import ( + Optional, + Union, + Literal, +) import jax.numpy as jnp -from jaxtyping import Num +from jaxtyping import ( + Bool, + Num, +) from simple_pytree import Pytree from gpjax.typing import Array @@ -30,12 +37,19 @@ class Dataset(Pytree): Attributes ---------- - X (Optional[Num[Array, "N D"]]): Input data. - y (Optional[Num[Array, "N Q"]]): Output data. + X (Optional[Num[Array, "N D"]]): input data. + y: (Optional[Num[Array, "N Q"]]): output data. + mask: (Optional[Union[Bool[Array, "N Q"], Literal["infer automatically"]]]): mask for the output data. + Users can optionally specify a pre-computed mask, or explicitly pass `None` which + means no mask will be used. Defaults to `"infer automatically"`, which means that + the mask will be computed from the output data, or set to `None` if no output data is provided. """ X: Optional[Num[Array, "N D"]] = None y: Optional[Num[Array, "N Q"]] = None + mask: Optional[ + Union[Bool[Array, "N Q"], Literal["infer automatically"]] + ] = "infer automatically" def __post_init__(self) -> None: r"""Checks that the shapes of $`X`$ and $`y`$ are compatible, @@ -43,6 +57,21 @@ def __post_init__(self) -> None: _check_shape(self.X, self.y) _check_precision(self.X, self.y) + if isinstance(self.mask, str): + if not self.mask == "infer automatically": + raise ValueError( + f"mask must be either the string 'infer automatically', None, or a boolean array." + f" Got mask={self.mask}." + ) + elif self.y is not None: + mask = jnp.isnan(self.y) + if jnp.any(mask): + self.mask = mask + else: + self.mask = None + else: + self.mask = None + def __repr__(self) -> str: r"""Returns a string representation of the dataset.""" repr = ( @@ -63,6 +92,7 @@ def __add__(self, other: "Dataset") -> "Dataset": r"""Combine two datasets. Right hand dataset is stacked beneath the left.""" X = None y = None + mask = None if self.X is not None and other.X is not None: X = jnp.concatenate((self.X, other.X)) @@ -70,7 +100,14 @@ def __add__(self, other: "Dataset") -> "Dataset": if self.y is not None and other.y is not None: y = jnp.concatenate((self.y, other.y)) - return Dataset(X=X, y=y) + self_m_exists = self.mask is not None + other_m_exists = other.mask is not None + self_m = self.mask if self_m_exists else jnp.zeros(self.y.shape, dtype=bool) + other_m = other.mask if other_m_exists else jnp.zeros(other.y.shape, dtype=bool) + if self_m_exists or other_m_exists: + mask = jnp.concatenate((self_m, other_m)) + + return Dataset(X=X, y=y, mask=mask) @property def n(self) -> int: diff --git a/gpjax/fit.py b/gpjax/fit.py index e5ad9d1d2..69b6a699a 100644 --- a/gpjax/fit.py +++ b/gpjax/fit.py @@ -182,12 +182,12 @@ def get_batch(train_data: Dataset, batch_size: int, key: KeyArray) -> Dataset: ------- Dataset: The batched dataset. """ - x, y, n = train_data.X, train_data.y, train_data.n + x, y, n, mask = train_data.X, train_data.y, train_data.n, train_data.mask # Subsample mini-batch indices with replacement. indices = jr.choice(key, n, (batch_size,), replace=True) - return Dataset(X=x[indices], y=y[indices]) + return Dataset(X=x[indices], y=y[indices], mask=mask[indices] if mask else None) def _check_model(model: Any) -> None: diff --git a/gpjax/gaussian_distribution.py b/gpjax/gaussian_distribution.py index 8e10b386c..e0125b746 100644 --- a/gpjax/gaussian_distribution.py +++ b/gpjax/gaussian_distribution.py @@ -22,7 +22,10 @@ from jax import vmap import jax.numpy as jnp import jax.random as jr -from jaxtyping import Float +from jaxtyping import ( + Bool, + Float, +) import tensorflow_probability.substrates.jax as tfp from gpjax.linops import ( @@ -149,11 +152,14 @@ def entropy(self) -> ScalarFloat: self.event_shape[0] * (1.0 + jnp.log(2.0 * jnp.pi)) + self.scale.log_det() ) - def log_prob(self, y: Float[Array, " N"]) -> ScalarFloat: + def log_prob( + self, y: Float[Array, " N"], mask: Optional[Bool[Array, " N"]] = None + ) -> ScalarFloat: r"""Calculates the log pdf of the multivariate Gaussian. Args: - y (Float[Array, " N"]): The value to calculate the log probability of. + y (Optional[Float[Array, " N"]]): the value of which to calculate the log probability. + mask: (Optional[Bool[Array, " N"]]): the mask for missing values in y. Returns ------- @@ -162,6 +168,13 @@ def log_prob(self, y: Float[Array, " N"]) -> ScalarFloat: mu = self.loc sigma = self.scale n = mu.shape[-1] + if mask is not None: + y = jnp.where(mask, 0.0, y) + mu = jnp.where(mask, 0.0, mu) + sigma_masked = jnp.where(mask[None] + mask[:, None], 0.0, sigma.matrix) + sigma = sigma.replace( + matrix=jnp.where(jnp.diag(mask), 1 / (2 * jnp.pi), sigma_masked) + ) # diff, y - µ diff = y - mu diff --git a/gpjax/gps.py b/gpjax/gps.py index e9739a3f0..ec8c1f402 100644 --- a/gpjax/gps.py +++ b/gpjax/gps.py @@ -476,7 +476,7 @@ def predict( distribution as a `GaussianDistribution`. """ # Unpack training data - x, y, n = train_data.X, train_data.y, train_data.n + x, y, n, mask = train_data.X, train_data.y, train_data.n, train_data.mask # Unpack test inputs t, n_test = test_inputs, test_inputs.shape[0] @@ -491,11 +491,23 @@ def predict( # Σ = Kxx + Io² Sigma = Kxx + identity(n) * obs_noise + if mask is not None: + y = jnp.where(mask, 0.0, y) + mx = jnp.where(mask, 0.0, mx) + Sigma_masked = jnp.where(mask + mask.T, 0.0, Sigma.matrix) + Sigma = Sigma.replace( + matrix=jnp.where( + jnp.diag(jnp.squeeze(mask)), 1 / (2 * jnp.pi), Sigma_masked + ) + ) + mean_t = self.prior.mean_function(t) Ktt = self.prior.kernel.gram(t) Kxt = self.prior.kernel.cross_covariance(x, t) # Σ⁻¹ Kxt + if mask is not None: + Kxt = jnp.where(mask * jnp.ones((1, n_test), dtype=bool), 0.0, Kxt) Sigma_inv_Kxt = Sigma.solve(Kxt) # μt + Ktx (Kxx + Io²)⁻¹ (y - μx) diff --git a/gpjax/linops/dense_linear_operator.py b/gpjax/linops/dense_linear_operator.py index 629ec9eba..ad98ee9f8 100644 --- a/gpjax/linops/dense_linear_operator.py +++ b/gpjax/linops/dense_linear_operator.py @@ -48,7 +48,9 @@ class DenseLinearOperator(LinearOperator): matrix: Float[Array, "N N"] - def __init__(self, matrix: Float[Array, "N N"], dtype: jnp.dtype = None) -> None: + def __init__( + self, matrix: Float[Array, "N N"], dtype: jnp.dtype = None, shape: tuple = None + ) -> None: """Initialize the covariance operator. Args: diff --git a/gpjax/objectives.py b/gpjax/objectives.py index 3481e2958..8b1adbea0 100644 --- a/gpjax/objectives.py +++ b/gpjax/objectives.py @@ -129,7 +129,9 @@ def step( # p(y | x, θ), where θ are the model hyperparameters: mll = GaussianDistribution(jnp.atleast_1d(mx.squeeze()), Sigma) - return self.constant * (mll.log_prob(jnp.atleast_1d(y.squeeze())).squeeze()) + return self.constant * ( + mll.log_prob(jnp.atleast_1d(y.squeeze()), mask=train_data.mask).squeeze() + ) class LogPosteriorDensity(AbstractObjective): diff --git a/tests/test_dataset.py b/tests/test_dataset.py index 38c277528..a9465e4f2 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -24,6 +24,7 @@ from jax.config import config import jax.numpy as jnp +import jax.random as jr import jax.tree_util as jtu import pytest @@ -160,6 +161,45 @@ def test_y_none(n: int, in_dim: int) -> None: assert jtu.tree_leaves(D) == [x] +@pytest.mark.parametrize("n", [1, 2, 10]) +@pytest.mark.parametrize("out_dim", [1, 2, 10]) +@pytest.mark.parametrize("in_dim", [1, 2, 10]) +def test_dataset_missing(n: int, in_dim: int, out_dim: int) -> None: + # Create dataset + x = jnp.ones((n, in_dim)) + y = jr.normal(jr.PRNGKey(123), (n, out_dim)) + y = y.at[y < 0].set(jnp.nan) + mask = jnp.isnan(y) + D = Dataset(X=x, y=y) + + # Check mask + assert D.mask is not None + assert jnp.array_equal(D.mask, mask) + + # Create second dataset + x2 = 2 * jnp.ones((n, in_dim)) + y2 = 2 * jnp.ones((n, out_dim)) + D2 = Dataset(X=x2, y=y2) + + # Add datasets + D2 = D + D2 + + # Check mask + assert jnp.sum(D2.mask) == jnp.sum(D.mask) + + # Test dataset shapes + assert D.n == n + assert D.in_dim == in_dim + assert D.out_dim == out_dim + + # Check tree flatten + # lexicographic order: uppercase "X" comes before lowercase "m" + x_, mask_, y_ = jtu.tree_leaves(D) + assert jnp.allclose(x, x_) + assert jnp.array_equal(mask, mask_) + assert jnp.allclose(y, y_, equal_nan=True) + + @pytest.mark.parametrize( ("prec_x", "prec_y"), [ @@ -185,9 +225,7 @@ def test_precision_warning( if prec_y != jnp.float64: expected_warnings += 1 - with pytest.warns( - UserWarning, match=".* is not of type float64.*" - ) as record: + with pytest.warns(UserWarning, match=".* is not of type float64.*") as record: Dataset(X=x, y=y) assert len(record) == expected_warnings diff --git a/tests/test_gaussian_distribution.py b/tests/test_gaussian_distribution.py index bcdce5f3e..9db53327e 100644 --- a/tests/test_gaussian_distribution.py +++ b/tests/test_gaussian_distribution.py @@ -149,3 +149,24 @@ def test_kl_divergence(n: int) -> None: with pytest.raises(ValueError): incompatible = GaussianDistribution(loc=jnp.ones((2 * n,))) incompatible.kl_divergence(dist_a) + + +@pytest.mark.parametrize("n", [5, 100]) +def test_masked_log_prob(n): + key_mean, key_sqrt = jr.split(_key, 2) + mean = jr.uniform(key_mean, shape=(n,)) + sqrt = jr.uniform(key_sqrt, shape=(n, n)) + covariance = sqrt @ sqrt.T + y = jr.normal(_key, shape=(n,)) + y = y.at[jr.choice(key_sqrt, y.shape[0], (1,))].set(jnp.nan) + mask = jnp.isnan(y) + + # check that cholesky does not error + _L = jnp.linalg.cholesky(covariance) # noqa: F841 + + # check that masked log_prob is equal to tfp log_prob with missing values removed + dist = GaussianDistribution(loc=mean, scale=DenseLinearOperator(covariance)) + tfp_dist = MultivariateNormalFullCovariance( + loc=mean[~mask], covariance_matrix=covariance[~mask][:, ~mask] + ) + assert approx_equal(dist.log_prob(y, mask=mask), tfp_dist.log_prob(y[~mask])) From c5eb47b4b2a1a231ad6863755b9fc89cab3a49cb Mon Sep 17 00:00:00 2001 From: Thomas Christie Date: Fri, 25 Aug 2023 17:26:46 +0100 Subject: [PATCH 34/76] Bump `jax` and `jaxlib` versions (#366) * Bump `jax` and `jaxlib` versions In response to issue (https://github.com/google/jax/issues/15951) causing us to pin `jaxlib` being fixed. * Bump `orbax-checkpoint` version --- poetry.lock | 5404 +++++++++++++++++++++++------------------------- pyproject.toml | 6 +- 2 files changed, 2587 insertions(+), 2823 deletions(-) diff --git a/poetry.lock b/poetry.lock index c9a80df57..3da071921 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,26 +1,37 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + [[package]] name = "absl-py" version = "1.4.0" description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, + {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, +] [[package]] name = "absolufy-imports" version = "0.3.1" description = "A tool to automatically replace relative imports with absolute ones." -category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "absolufy_imports-0.3.1-py2.py3-none-any.whl", hash = "sha256:49bf7c753a9282006d553ba99217f48f947e3eef09e18a700f8a82f75dc7fc5c"}, + {file = "absolufy_imports-0.3.1.tar.gz", hash = "sha256:c90638a6c0b66826d1fb4880ddc20ef7701af34192c94faf40b95d32b59f9793"}, +] [[package]] name = "affine" version = "2.4.0" description = "Matrices describing affine transformation of the plane" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, + {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, +] [package.extras] dev = ["coveralls", "flake8", "pydocstyle"] @@ -30,9 +41,97 @@ test = ["pytest (>=4.6)", "pytest-cov"] name = "aiohttp" version = "3.8.4" description = "Async http client/server framework (asyncio)" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"}, + {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"}, + {file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"}, + {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"}, + {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"}, + {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"}, + {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"}, + {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"}, + {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"}, + {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"}, + {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"}, + {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"}, + {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"}, + {file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"}, + {file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"}, + {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"}, + {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"}, + {file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"}, + {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"}, + {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"}, + {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"}, + {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"}, + {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"}, + {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"}, + {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"}, + {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"}, + {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"}, + {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"}, + {file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"}, + {file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"}, + {file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"}, + {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"}, + {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"}, + {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"}, + {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"}, + {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"}, + {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"}, + {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"}, + {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"}, + {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"}, + {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"}, + {file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"}, + {file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"}, + {file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"}, + {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"}, + {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"}, + {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"}, + {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"}, + {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"}, + {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"}, + {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"}, + {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"}, + {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"}, + {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"}, + {file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"}, + {file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"}, + {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"}, + {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"}, + {file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"}, + {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"}, + {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"}, + {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"}, + {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"}, + {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"}, + {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"}, + {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"}, + {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"}, + {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"}, + {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"}, + {file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"}, + {file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"}, + {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"}, + {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"}, + {file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"}, + {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"}, + {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"}, + {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"}, + {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"}, + {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"}, + {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"}, + {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"}, + {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"}, + {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"}, + {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"}, + {file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"}, + {file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"}, + {file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"}, +] [package.dependencies] aiosignal = ">=1.1.2" @@ -50,9 +149,12 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] [package.dependencies] frozenlist = ">=1.1.0" @@ -61,17 +163,23 @@ frozenlist = ">=1.1.0" name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] [[package]] name = "argcomplete" version = "2.1.2" description = "Bash tab completion for argparse" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "argcomplete-2.1.2-py3-none-any.whl", hash = "sha256:4ba9cdaa28c361d251edce884cd50b4b1215d65cdc881bd204426cdde9f52731"}, + {file = "argcomplete-2.1.2.tar.gz", hash = "sha256:fc82ef070c607b1559b5c720529d63b54d9dcf2dcfc2632b10e6372314a34457"}, +] [package.extras] lint = ["flake8", "mypy"] @@ -81,9 +189,12 @@ test = ["coverage", "flake8", "mypy", "pexpect", "wheel"] name = "astroid" version = "2.15.4" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false python-versions = ">=3.7.2" +files = [ + {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, + {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, +] [package.dependencies] lazy-object-proxy = ">=1.4.0" @@ -97,9 +208,12 @@ wrapt = [ name = "asttokens" version = "2.2.1" description = "Annotate AST trees with source code positions" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, + {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, +] [package.dependencies] six = "*" @@ -111,9 +225,12 @@ test = ["astroid", "pytest"] name = "astunparse" version = "1.6.3" description = "An AST unparser for Python" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, + {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, +] [package.dependencies] six = ">=1.6.1,<2.0" @@ -123,17 +240,23 @@ wheel = ">=0.23.0,<1.0" name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] [[package]] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] @@ -146,17 +269,23 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] [[package]] name = "beartype" version = "0.13.1" description = "Unbearably fast runtime type checking in pure Python." -category = "main" optional = false python-versions = ">=3.7.0" +files = [ + {file = "beartype-0.13.1-py3-none-any.whl", hash = "sha256:c3097b487e57bc278f1b55da8863b704b2a786c46483a6d3df39ab6fe2523d80"}, + {file = "beartype-0.13.1.tar.gz", hash = "sha256:2903947a8a1eb6030264e30108aa72cb1a805cfc9050c0f4014c4aed3a17a00b"}, +] [package.extras] all = ["typing-extensions (>=3.10.0.0)"] @@ -169,9 +298,12 @@ test-tox-coverage = ["coverage (>=5.5)"] name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "dev" optional = false python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] [package.dependencies] soupsieve = ">1.2" @@ -184,9 +316,35 @@ lxml = ["lxml"] name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, +] [package.dependencies] click = ">=8.0.0" @@ -207,9 +365,12 @@ uvloop = ["uvloop (>=0.15.2)"] name = "blackjax" version = "0.9.6" description = "Flexible and fast inference in Python" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "blackjax-0.9.6-py3-none-any.whl", hash = "sha256:d1c20dd15a63944a7b5c835bac4900aadf8630bedb0d7e51ab7fc63255eb0dd7"}, + {file = "blackjax-0.9.6.tar.gz", hash = "sha256:fb708f183d714750feb475fb87b8162fc1641309f30ee42fd38a5dec82733868"}, +] [package.dependencies] fastprogress = ">=0.2.0" @@ -221,9 +382,12 @@ jaxopt = ">=0.4.2" name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, + {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, +] [package.dependencies] six = ">=1.9.0" @@ -236,25 +400,96 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -category = "main" optional = false python-versions = "*" +files = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, +] [[package]] name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, +] [[package]] name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] [package.dependencies] pycparser = "*" @@ -263,42 +498,127 @@ pycparser = "*" name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, + {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, +] [[package]] name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" optional = false python-versions = ">=3.7.0" - -[[package]] -name = "chex" -version = "0.1.7" -description = "Chex: Testing made fun, in JAX!" -category = "main" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -absl-py = ">=0.9.0" -dm-tree = ">=0.1.5" -jax = ">=0.4.6" -jaxlib = ">=0.1.37" -numpy = ">=1.18.0" -toolz = ">=0.9.0" -typing-extensions = {version = ">=4.2.0", markers = "python_version < \"3.11\""} - -[[package]] -name = "click" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] + +[[package]] +name = "chex" +version = "0.1.7" +description = "Chex: Testing made fun, in JAX!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "chex-0.1.7-py3-none-any.whl", hash = "sha256:9f583015303b1205443843c0b55849bb287f1dfdbd22d9907b1ebb04f964d93e"}, + {file = "chex-0.1.7.tar.gz", hash = "sha256:74ed49799ac4d229881456d468136f1b19a9f9839e3de72b058824e2a4f4dedd"}, +] + +[package.dependencies] +absl-py = ">=0.9.0" +dm-tree = ">=0.1.5" +jax = ">=0.4.6" +jaxlib = ">=0.1.37" +numpy = ">=1.18.0" +toolz = ">=0.9.0" +typing-extensions = {version = ">=4.2.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -307,9 +627,12 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] [package.dependencies] click = ">=4.0" @@ -321,9 +644,12 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "cligj" version = "0.7.2" description = "Click params for commmand line interfaces to GeoJSON" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" +files = [ + {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, + {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, +] [package.dependencies] click = ">=4.0" @@ -335,17 +661,23 @@ test = ["pytest-cov"] name = "cloudpickle" version = "2.2.1" description = "Extended pickling support for Python objects" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, + {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, +] [[package]] name = "codespell" version = "2.2.4" description = "Codespell" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "codespell-2.2.4-py3-none-any.whl", hash = "sha256:7d984b8130108e6f82524b7d09f8b7bf2fb1e398c5d4b37d9e2bd310145b3e29"}, + {file = "codespell-2.2.4.tar.gz", hash = "sha256:0b4620473c257d9cde1ff8998b26b2bb209a35c2b7489f5dc3436024298ce83a"}, +] [package.extras] dev = ["Pygments", "build", "chardet", "flake8", "flake8-pyproject", "pytest", "pytest-cov", "pytest-dependency", "tomli"] @@ -357,17 +689,23 @@ types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" 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 = "colorlog" version = "6.7.0" description = "Add colours to the output of Python's logging module." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, +] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -379,9 +717,12 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] name = "comm" version = "0.1.3" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"}, + {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"}, +] [package.dependencies] traitlets = ">=5.3" @@ -395,9 +736,65 @@ typing = ["mypy (>=0.990)"] name = "contourpy" version = "1.0.7" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, + {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"}, + {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"}, + {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"}, + {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"}, + {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"}, + {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"}, + {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"}, + {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"}, + {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"}, + {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"}, + {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"}, +] [package.dependencies] numpy = ">=1.16" @@ -413,9 +810,61 @@ test-no-images = ["pytest"] name = "coverage" version = "7.2.5" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"}, + {file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"}, + {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"}, + {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"}, + {file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"}, + {file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"}, + {file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"}, + {file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"}, + {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"}, + {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"}, + {file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"}, + {file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"}, + {file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"}, + {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"}, + {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"}, + {file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"}, + {file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"}, + {file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"}, + {file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"}, + {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"}, + {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"}, + {file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"}, + {file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"}, + {file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"}, + {file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"}, + {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"}, + {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"}, + {file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"}, + {file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"}, + {file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"}, + {file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -427,41 +876,72 @@ toml = ["tomli"] name = "cycler" version = "0.11.0" description = "Composable style cycles" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] [[package]] name = "debugpy" version = "1.6.7" description = "An implementation of the Debug Adapter Protocol for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"}, + {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"}, + {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"}, + {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"}, + {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"}, + {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"}, + {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"}, + {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"}, + {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"}, + {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"}, + {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"}, + {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"}, + {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"}, + {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"}, + {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"}, + {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"}, + {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"}, + {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"}, +] [[package]] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] [[package]] name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + [[package]] name = "dill" version = "0.3.6" description = "serialize all of python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, + {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, +] [package.extras] graph = ["objgraph (>=1.7.2)"] @@ -470,25 +950,71 @@ graph = ["objgraph (>=1.7.2)"] name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, + {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, +] [[package]] name = "dm-tree" version = "0.1.8" description = "Tree is a library for working with nested data structures." -category = "main" optional = false python-versions = "*" +files = [ + {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, + {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, + {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, + {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, + {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, + {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, + {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, +] [[package]] name = "etils" version = "1.2.0" description = "Collection of common python utils" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "etils-1.2.0-py3-none-any.whl", hash = "sha256:c6585069b387fdbeed6a2c571b8bcf312ecdb577c95065461e5fad9ed1973989"}, + {file = "etils-1.2.0.tar.gz", hash = "sha256:29d369e2dcf43960d9ee338330579d04badd606c88f015f4e1a38d3adbe446d8"}, +] [package.extras] all = ["etils[array-types]", "etils[eapp]", "etils[ecolab]", "etils[edc]", "etils[enp]", "etils[epath]", "etils[epy]", "etils[etqdm]", "etils[etree-dm]", "etils[etree-jax]", "etils[etree-tf]", "etils[etree]"] @@ -511,9 +1037,12 @@ lazy-imports = ["etils[ecolab]"] name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, +] [package.extras] test = ["pytest (>=6)"] @@ -522,9 +1051,12 @@ test = ["pytest (>=6)"] name = "execnet" version = "1.9.0" description = "execnet: rapid multi-Python deployment" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, + {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, +] [package.extras] testing = ["pre-commit"] @@ -533,9 +1065,12 @@ testing = ["pre-commit"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, + {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, +] [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] @@ -544,9 +1079,12 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "fastjsonschema" version = "2.16.3" description = "Fastest Python implementation of JSON schema" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, + {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, +] [package.extras] devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] @@ -555,17 +1093,23 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "fastprogress" version = "1.0.3" description = "A nested progress with plotting options for fastai" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "fastprogress-1.0.3-py3-none-any.whl", hash = "sha256:6dfea88f7a4717b0a8d6ee2048beae5dbed369f932a368c5dd9caff34796f7c5"}, + {file = "fastprogress-1.0.3.tar.gz", hash = "sha256:7a17d2b438890f838c048eefce32c4ded47197ecc8ea042cecc33d3deb8022f5"}, +] [[package]] name = "filelock" version = "3.12.0" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, + {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, +] [package.extras] docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] @@ -575,9 +1119,30 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "p name = "fiona" version = "1.9.3" description = "Fiona reads and writes spatial data files" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "Fiona-1.9.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0e9141bdb8031419ed2f04c6da02ae12c3044a81987065e05ff40f39cc35e042"}, + {file = "Fiona-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c0251a57305e6bea3f0a8e8306c0bd05e2b0e30b8a294d7bdc429d5fceca68d"}, + {file = "Fiona-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:894127efde8141bb9383dc4dc890c732f3bfe4d601c3d1020a24fa3c24a8c4a8"}, + {file = "Fiona-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:11ee3d3e6bb5d16f6f1643ffcde7ac4dfa5fbe98a26ce2af05c3c5426ce248d7"}, + {file = "Fiona-1.9.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c99e9bca9e3d6be03a71e9b2f6ba66d446eae9b27df37c1f6b45483b2f215ca0"}, + {file = "Fiona-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a894362c1cf9f33ee931e96cfd4021d3a18f6ccf8c36b87df42a0a494e23545"}, + {file = "Fiona-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0761ff656d07aaef7a7274b74816e16485f0f15e77a962c107cd4a1cfb4757"}, + {file = "Fiona-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:2e61caeabda88ab5fa45db373c2afd6913844b4452c0f2e3e9d924c60bc76fa3"}, + {file = "Fiona-1.9.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:00628c5a3dd7e9bc037ba0487fc3b9f7163107e0a9794bd4c32c471ab65f3a45"}, + {file = "Fiona-1.9.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:95927ddd9afafdb0243bb83bf234557dcdb35bf0e888fd920ff82ffa80f6a53a"}, + {file = "Fiona-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d1064e82a7fed73ce60ce9ce4f65b5a6558fb5b532a13130a17f132ed122ec75"}, + {file = "Fiona-1.9.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:65b096148bfe9a64d87d91ba8e7ff940a5aef8cbffc6738a70e289c6384e1cca"}, + {file = "Fiona-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:38d0d78d4e061592af3441c5962072b0456307246c9c6f412ad38ebef11d2903"}, + {file = "Fiona-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee9b2ec9f0fb4b3798d607a94a5586b403fc27fea06e3e7ac2924c0785d4df61"}, + {file = "Fiona-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:258151f26683a44ed715c09930a42e0b39b3b3444b438ec6e32633f7056740fa"}, + {file = "Fiona-1.9.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:f1fcadad17b00d342532dc51a47128005f8ced01a320fa6b72c8ef669edf3057"}, + {file = "Fiona-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85b6694227ee4e00dfa52c6a9fcc89f1051aaf67df5fbd1faa33fb02c62a6203"}, + {file = "Fiona-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e661deb7a8722839bd27eae74f63f0e480559774cc755598dfa6c51bdf18be3d"}, + {file = "Fiona-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:a57812a584b4a2fb4ffdfaa9135dc38312989f7cd2823ecbd23e11eade5eb7fe"}, + {file = "Fiona-1.9.3.tar.gz", hash = "sha256:60f3789ad9633c3a26acf7cbe39e82e3c7a12562c59af1d599fc3e4e8f7f8f25"}, +] [package.dependencies] attrs = ">=19.2.0" @@ -598,9 +1163,12 @@ test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] name = "flax" version = "0.6.10" description = "Flax: A neural network library for JAX designed for flexibility" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "flax-0.6.10-py3-none-any.whl", hash = "sha256:8dccc7b84b00ff6f59a36dc0e79f5919498cfeb009a41f8c07f68bf2513198db"}, + {file = "flax-0.6.10.tar.gz", hash = "sha256:e2174a0df7bb4921f29b2cbd33f55ddf6eed161d6df61809fe374a25e473fb2f"}, +] [package.dependencies] jax = ">=0.4.2" @@ -621,9 +1189,12 @@ testing = ["atari-py (==0.2.5)", "clu", "einops", "gym (==0.18.3)", "jaxlib", "j name = "fonttools" version = "4.39.4" description = "Tools to manipulate font files" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"}, + {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"}, +] [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)"] @@ -643,17 +1214,95 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.3.3" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, + {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, + {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, + {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, + {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, + {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, + {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, + {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, + {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, + {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, + {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, +] [[package]] name = "fsspec" version = "2023.5.0" description = "File-system specification" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.5.0-py3-none-any.whl", hash = "sha256:51a4ad01a5bb66fcc58036e288c0d53d3975a0df2a5dc59a93b59bade0391f2a"}, + {file = "fsspec-2023.5.0.tar.gz", hash = "sha256:b3b56e00fb93ea321bc9e5d9cf6f8522a0198b20eb24e02774d329e9c6fb84ce"}, +] [package.extras] abfs = ["adlfs"] @@ -683,17 +1332,23 @@ tqdm = ["tqdm"] name = "gast" version = "0.5.4" description = "Python AST that abstracts the underlying Python version" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "gast-0.5.4-py3-none-any.whl", hash = "sha256:6fc4fa5fa10b72fb8aab4ae58bcb023058386e67b6fa2e3e34cec5c769360316"}, + {file = "gast-0.5.4.tar.gz", hash = "sha256:9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97"}, +] [[package]] name = "geopandas" version = "0.12.2" description = "Geographic pandas extensions" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "geopandas-0.12.2-py3-none-any.whl", hash = "sha256:0a470e4bf6f5367e6fd83ab6b40405e0b805c8174665bbcb7c4077ed90202912"}, + {file = "geopandas-0.12.2.tar.gz", hash = "sha256:0acdacddefa176525e4da6d9aeeece225da26055c4becdc6e97cf40fa97c27f4"}, +] [package.dependencies] fiona = ">=1.8" @@ -706,9 +1361,12 @@ shapely = ">=1.7" name = "ghp-import" version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] [package.dependencies] python-dateutil = ">=2.8.1" @@ -720,9 +1378,12 @@ dev = ["flake8", "markdown", "twine", "wheel"] name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, + {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, +] [package.dependencies] smmap = ">=3.0.1,<6" @@ -731,9 +1392,12 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.31" description = "GitPython is a Python library used to interact with Git repositories" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, + {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, +] [package.dependencies] gitdb = ">=4.0.1,<5" @@ -742,9 +1406,12 @@ gitdb = ">=4.0.1,<5" name = "griffe" version = "0.27.4" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "griffe-0.27.4-py3-none-any.whl", hash = "sha256:685350067286229e80a18b8989d6acbd43abdf8b763591221d19c56f4108549e"}, + {file = "griffe-0.27.4.tar.gz", hash = "sha256:088c25fb22f8d1f1add5d3b58a86a3969993181a36ca55b3fa33096a3f3b1a23"}, +] [package.dependencies] colorama = ">=0.4" @@ -753,9 +1420,12 @@ colorama = ">=0.4" name = "identify" version = "2.5.24" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"}, + {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"}, +] [package.extras] license = ["ukkonen"] @@ -764,17 +1434,23 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" 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 = "importlib-metadata" version = "6.6.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, + {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, +] [package.dependencies] zipp = ">=0.5" @@ -788,9 +1464,12 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, + {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, +] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} @@ -803,17 +1482,23 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" 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 = "interrogate" version = "1.5.0" description = "Interrogate a codebase for docstring coverage." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "interrogate-1.5.0-py3-none-any.whl", hash = "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a"}, + {file = "interrogate-1.5.0.tar.gz", hash = "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c"}, +] [package.dependencies] attrs = "*" @@ -833,9 +1518,12 @@ tests = ["pytest", "pytest-cov", "pytest-mock"] name = "ipykernel" version = "6.23.0" description = "IPython Kernel for Jupyter" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.23.0-py3-none-any.whl", hash = "sha256:fc886f1dcdc0ec17f277e4d21fd071c857d381adcb04f3f3735d25325ca323c6"}, + {file = "ipykernel-6.23.0.tar.gz", hash = "sha256:bd6f487d9e2744c84f6e667d46462d7647a4c862e70e08282f05a52b9d4b705f"}, +] [package.dependencies] appnope = {version = "*", markers = "platform_system == \"Darwin\""} @@ -843,7 +1531,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -863,9 +1551,12 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" name = "ipython" version = "8.12.2" description = "IPython: Productive Interactive Computing" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, + {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, +] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -899,9 +1590,12 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "ipywidgets" version = "8.0.6" description = "Jupyter interactive widgets" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "ipywidgets-8.0.6-py3-none-any.whl", hash = "sha256:a60bf8d2528997e05ac83fd19ea2fbe65f2e79fbe1b2b35779bdfc46c2941dcc"}, + {file = "ipywidgets-8.0.6.tar.gz", hash = "sha256:de7d779f2045d60de9f6c25f653fdae2dba57898e6a1284494b3ba20b6893bb8"}, +] [package.dependencies] ipykernel = ">=4.5.1" @@ -917,9 +1611,12 @@ test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] [package.extras] colors = ["colorama (>=0.4.3)"] @@ -929,13 +1626,16 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jax" -version = "0.4.9" +version = "0.4.13" description = "Differentiate, compile, and transform Numpy code." -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "jax-0.4.13.tar.gz", hash = "sha256:03bfe6749dfe647f16f15f6616638adae6c4a7ca7167c75c21961ecfd3a3baaa"}, +] [package.dependencies] +importlib_metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} ml_dtypes = ">=0.1.0" numpy = ">=1.21" opt_einsum = "*" @@ -943,38 +1643,60 @@ scipy = ">=1.7" [package.extras] australis = ["protobuf (>=3.13,<4)"] -ci = ["jaxlib (==0.4.7)"] -cpu = ["jaxlib (==0.4.9)"] -cuda = ["jaxlib (==0.4.9+cuda11.cudnn86)"] -cuda11-cudnn82 = ["jaxlib (==0.4.9+cuda11.cudnn82)"] -cuda11-cudnn86 = ["jaxlib (==0.4.9+cuda11.cudnn86)"] -cuda11-local = ["jaxlib (==0.4.9+cuda11.cudnn86)"] -cuda11-pip = ["jaxlib (==0.4.9+cuda11.cudnn86)", "nvidia-cublas-cu11 (>=11.11)", "nvidia-cuda-cupti-cu11 (>=11.8)", "nvidia-cuda-nvcc-cu11 (>=11.8)", "nvidia-cuda-runtime-cu11 (>=11.8)", "nvidia-cudnn-cu11 (>=8.6)", "nvidia-cufft-cu11 (>=10.9)", "nvidia-cusolver-cu11 (>=11.4)", "nvidia-cusparse-cu11 (>=11.7)"] -cuda12-local = ["jaxlib (==0.4.9+cuda12.cudnn88)"] -cuda12-pip = ["jaxlib (==0.4.9+cuda12.cudnn88)", "nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc-cu12", "nvidia-cuda-runtime-cu12", "nvidia-cudnn-cu12", "nvidia-cufft-cu12", "nvidia-cusolver-cu12", "nvidia-cusparse-cu12"] -minimum-jaxlib = ["jaxlib (==0.4.7)"] -tpu = ["jaxlib (==0.4.9)", "libtpu-nightly (==0.1.dev20230509)", "requests"] +ci = ["jaxlib (==0.4.12)"] +cpu = ["jaxlib (==0.4.13)"] +cuda = ["jaxlib (==0.4.13+cuda11.cudnn86)"] +cuda11-cudnn86 = ["jaxlib (==0.4.13+cuda11.cudnn86)"] +cuda11-local = ["jaxlib (==0.4.13+cuda11.cudnn86)"] +cuda11-pip = ["jaxlib (==0.4.13+cuda11.cudnn86)", "nvidia-cublas-cu11 (>=11.11)", "nvidia-cuda-cupti-cu11 (>=11.8)", "nvidia-cuda-nvcc-cu11 (>=11.8)", "nvidia-cuda-runtime-cu11 (>=11.8)", "nvidia-cudnn-cu11 (>=8.8)", "nvidia-cufft-cu11 (>=10.9)", "nvidia-cusolver-cu11 (>=11.4)", "nvidia-cusparse-cu11 (>=11.7)"] +cuda12-local = ["jaxlib (==0.4.13+cuda12.cudnn89)"] +cuda12-pip = ["jaxlib (==0.4.13+cuda12.cudnn89)", "nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc-cu12", "nvidia-cuda-runtime-cu12", "nvidia-cudnn-cu12 (>=8.9)", "nvidia-cufft-cu12", "nvidia-cusolver-cu12", "nvidia-cusparse-cu12"] +minimum-jaxlib = ["jaxlib (==0.4.11)"] +tpu = ["jaxlib (==0.4.13)", "libtpu-nightly (==0.1.dev20230622)"] [[package]] name = "jaxlib" -version = "0.4.7" +version = "0.4.13" description = "XLA library for JAX" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "jaxlib-0.4.13-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:532ebc4fb11386282ad63b83941d4557f4038c1144acf026f1f8565f64c7e9c0"}, + {file = "jaxlib-0.4.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a259bb35429bfbd3b76e43019dfc8f7d6ea94bb217400b78f7d0824ce07a58ac"}, + {file = "jaxlib-0.4.13-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:ea1bc9811ef7d73a15e3213115e88fe7f5d14b59d95027bea9fccc98e5a14af8"}, + {file = "jaxlib-0.4.13-cp310-cp310-win_amd64.whl", hash = "sha256:fde66a93e9be89d99e5792f677ed8e319667d6b2396865b1c52c1312844c47f9"}, + {file = "jaxlib-0.4.13-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:49690fcdd26560515fd15399fc3a44777e0bfc5db5c48fe76ff7bc7228e8b2fb"}, + {file = "jaxlib-0.4.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4e9e34e5d8a6556f62fead14aee0b1614c2c6296f0078d8e6139d6aff109649"}, + {file = "jaxlib-0.4.13-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:8000c0d15c107328e8f7b7b3ac91dd822f5c287a80231882b620503ed141fa89"}, + {file = "jaxlib-0.4.13-cp311-cp311-win_amd64.whl", hash = "sha256:19ae4c316b17a49342432c69f7f89f190b975333f3f9e9e175f686a651bc7347"}, + {file = "jaxlib-0.4.13-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:522635d5e159401a386c79f1236c218c1f68fbb4ca6648115c3ad3c2c3f518ab"}, + {file = "jaxlib-0.4.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:411334d903df07dc1ace8d52fc53c17f6bc1d55aff7f6e0e5cf61ec149f758a0"}, + {file = "jaxlib-0.4.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:839173b2e9593f5e9a6d3c42852cd15070fe80a939246efbb5cf40eec815de89"}, + {file = "jaxlib-0.4.13-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c230ef85712e608d0f048869766a5a63afeb2e72309943db0df9f959ab17307f"}, + {file = "jaxlib-0.4.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d19c05c15f962e098d49b45e2758aacf19330d192ec5395f9ef136f62db90edc"}, + {file = "jaxlib-0.4.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:b5c0a9737efd95fe18fd7715ce30dfce476546705ea8934aad6731777a9631a5"}, + {file = "jaxlib-0.4.13-cp39-cp39-win_amd64.whl", hash = "sha256:bebb4cf001f180dc431f9604daf930c2d9cc778e4dda26f401ac939b7bac912e"}, +] [package.dependencies] -ml-dtypes = ">=0.0.3" +ml-dtypes = ">=0.1.0" numpy = ">=1.21" scipy = ">=1.7" +[package.extras] +cuda11-pip = ["nvidia-cublas-cu11 (>=11.11)", "nvidia-cuda-cupti-cu11 (>=11.8)", "nvidia-cuda-nvcc-cu11 (>=11.8)", "nvidia-cuda-runtime-cu11 (>=11.8)", "nvidia-cudnn-cu11 (>=8.8)", "nvidia-cufft-cu11 (>=10.9)", "nvidia-cusolver-cu11 (>=11.4)", "nvidia-cusparse-cu11 (>=11.7)"] +cuda12-pip = ["nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc-cu12", "nvidia-cuda-runtime-cu12", "nvidia-cudnn-cu12 (>=8.9)", "nvidia-cufft-cu12", "nvidia-cusolver-cu12", "nvidia-cusparse-cu12"] + [[package]] name = "jaxopt" version = "0.6" description = "Hardware accelerated, batchable and differentiable optimizers in JAX." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "jaxopt-0.6-py3-none-any.whl", hash = "sha256:69af71c39969e9e5fa54bd50cbab3e18f6c32659d92e1bf56912a24c8ad0fca6"}, + {file = "jaxopt-0.6.tar.gz", hash = "sha256:19df9cb745ee39fa27f9ba4f01bbec5b0e3a8a1f60320aff553131a5f152c9fa"}, +] [package.dependencies] absl-py = ">=0.7.0" @@ -988,9 +1710,12 @@ scipy = ">=1.0.0" name = "jaxtyping" version = "0.2.19" description = "Type annotations and runtime checking for shape and dtype of JAX arrays, and PyTrees." -category = "main" optional = false python-versions = "~=3.8" +files = [ + {file = "jaxtyping-0.2.19-py3-none-any.whl", hash = "sha256:651352032799d422987e783fd1b77699b53c3bb28ffa644bbca5f75ec4fbb843"}, + {file = "jaxtyping-0.2.19.tar.gz", hash = "sha256:21ff4c3caec6781cadfe980b019dde856c1011e17d11dfe8589298040056325a"}, +] [package.dependencies] numpy = ">=1.20.0" @@ -1001,9 +1726,12 @@ typing-extensions = ">=3.7.4.1" name = "jedi" version = "0.18.2" description = "An autocompletion tool for Python that can be used for text editors." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, + {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, +] [package.dependencies] parso = ">=0.8.0,<0.9.0" @@ -1017,9 +1745,12 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "dev" 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" @@ -1031,17 +1762,23 @@ i18n = ["Babel (>=2.7)"] name = "joblib" version = "1.2.0" description = "Lightweight pipelining with Python functions" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"}, + {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"}, +] [[package]] name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] [package.dependencies] attrs = ">=17.4.0" @@ -1057,13 +1794,16 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jupyter-client" version = "8.2.0" description = "Jupyter protocol implementation and client libraries" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.2.0-py3-none-any.whl", hash = "sha256:b18219aa695d39e2ad570533e0d71fb7881d35a873051054a84ee2a17c4b7389"}, + {file = "jupyter_client-8.2.0.tar.gz", hash = "sha256:9fe233834edd0e6c0aa5f05ca2ab4bdea1842bfd2d8a932878212fc5301ddaf0"}, +] [package.dependencies] importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" @@ -1077,9 +1817,12 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt name = "jupyter-core" version = "5.3.0" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.3.0-py3-none-any.whl", hash = "sha256:d4201af84559bc8c70cead287e1ab94aeef3c512848dde077b7684b54d67730d"}, + {file = "jupyter_core-5.3.0.tar.gz", hash = "sha256:6db75be0c83edbf1b7c9f91ec266a9a24ef945da630f3120e1a0046dc13713fc"}, +] [package.dependencies] platformdirs = ">=2.5" @@ -1094,25 +1837,34 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, +] [[package]] name = "jupyterlab-widgets" version = "3.0.7" description = "Jupyter interactive widgets for JupyterLab" -category = "dev" optional = false python-versions = ">=3.7" - +files = [ + {file = "jupyterlab_widgets-3.0.7-py3-none-any.whl", hash = "sha256:c73f8370338ec19f1bec47254752d6505b03601cbd5a67e6a0b184532f73a459"}, + {file = "jupyterlab_widgets-3.0.7.tar.gz", hash = "sha256:c3a50ed5bf528a0c7a869096503af54702f86dda1db469aee1c92dc0c01b43ca"}, +] + [[package]] name = "jupytext" version = "1.14.5" description = "Jupyter notebooks as Markdown documents, Julia, Python or R scripts" -category = "dev" optional = false python-versions = "~=3.6" +files = [ + {file = "jupytext-1.14.5-py3-none-any.whl", hash = "sha256:a5dbe60d0ea158bbf82c2bce74aba8d0c220ad7edcda09e017c5eba229b34dc8"}, + {file = "jupytext-1.14.5.tar.gz", hash = "sha256:976e66be8056459a2067e0ec3ff68cc31e00c31895faf9eb893022d319e8f5b4"}, +] [package.dependencies] markdown-it-py = ">=1.0.0,<3.0.0" @@ -1129,17 +1881,89 @@ toml = ["toml"] name = "kiwisolver" version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] [[package]] name = "latexcodec" version = "2.0.1" description = "A lexer and codec to work with LaTeX code in Python." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, + {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, +] [package.dependencies] six = ">=1.4.1" @@ -1148,17 +1972,57 @@ six = ">=1.4.1" name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] [[package]] name = "linkify-it-py" version = "2.0.2" description = "Links recognition library with FULL unicode support." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, + {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, +] [package.dependencies] uc-micro-py = "*" @@ -1173,9 +2037,12 @@ test = ["coverage", "pytest", "pytest-cov"] name = "markdown" version = "3.3.7" description = "Python implementation of Markdown." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, + {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, +] [package.dependencies] importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} @@ -1187,9 +2054,12 @@ testing = ["coverage", "pyyaml"] name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, + {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, +] [package.dependencies] mdurl = ">=0.1,<1.0" @@ -1208,9 +2078,12 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markdown-katex" version = "202112.1034" description = "katex extension for Python Markdown" -category = "dev" optional = false python-versions = ">=2.7" +files = [ + {file = "markdown-katex-202112.1034.tar.gz", hash = "sha256:27892f4cdd6763816f00e4187d0475500697c090aba16630ec4803a6564bf810"}, + {file = "markdown_katex-202112.1034-py2.py3-none-any.whl", hash = "sha256:9ccc5b4b37db7592cc3ea113d763fafe9ffd1b1587e2c217d6145e44a10b4f6d"}, +] [package.dependencies] Markdown = {version = ">=3.0", markers = "python_version >= \"3.6\""} @@ -1221,17 +2094,110 @@ setuptools = "*" name = "markupsafe" version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, +] [[package]] name = "matplotlib" version = "3.7.1" description = "Python plotting package" -category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, + {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, + {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, + {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, + {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, + {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, + {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, + {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, + {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, + {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, + {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, + {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, +] [package.dependencies] contourpy = ">=1.0.1" @@ -1244,15 +2210,17 @@ packaging = ">=20.0" pillow = ">=6.2.0" pyparsing = ">=2.3.1" python-dateutil = ">=2.7" -setuptools_scm = ">=7" [[package]] name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] [package.dependencies] traitlets = "*" @@ -1261,17 +2229,23 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] name = "mdit-py-plugins" version = "0.3.5" description = "Collection of plugins for markdown-it-py" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, + {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, +] [package.dependencies] markdown-it-py = ">=1.0.0,<3.0.0" @@ -1285,17 +2259,23 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] [[package]] name = "mdx-truly-sane-lists" version = "1.3" description = "Extension for Python-Markdown that makes lists truly sane. Custom indents for nested lists and fix for messy linebreaks." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mdx_truly_sane_lists-1.3-py3-none-any.whl", hash = "sha256:b9546a4c40ff8f1ab692f77cee4b6bfe8ddf9cccf23f0a24e71f3716fe290a37"}, + {file = "mdx_truly_sane_lists-1.3.tar.gz", hash = "sha256:b661022df7520a1e113af7c355c62216b384c867e4f59fb8ee7ad511e6e77f45"}, +] [package.dependencies] Markdown = ">=2.6" @@ -1304,25 +2284,34 @@ Markdown = ">=2.6" name = "mergedeep" version = "1.3.4" description = "A deep merge function for 🐍." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] [[package]] name = "mistune" version = "2.0.5" description = "A sane Markdown parser with useful plugins and renderers" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, + {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, +] [[package]] name = "mkdocs" version = "1.4.3" description = "Project documentation with Markdown." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.4.3-py3-none-any.whl", hash = "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd"}, + {file = "mkdocs-1.4.3.tar.gz", hash = "sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57"}, +] [package.dependencies] click = ">=7.0" @@ -1345,9 +2334,12 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp name = "mkdocs-autorefs" version = "0.4.1" description = "Automatically link across pages in MkDocs." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, + {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, +] [package.dependencies] Markdown = ">=3.3" @@ -1357,9 +2349,11 @@ mkdocs = ">=1.1" name = "mkdocs-bibtex" version = "2.8.16" description = "An MkDocs plugin that enables managing citations with BibTex" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mkdocs-bibtex-2.8.16.tar.gz", hash = "sha256:d4f4d284a72a7a943ab427fff58e74409fb26eb0536f89f202c891fdda2eb50a"}, +] [package.dependencies] mkdocs = ">=1" @@ -1372,9 +2366,12 @@ validators = ">=0.19.0" name = "mkdocs-gen-files" version = "0.5.0" description = "MkDocs plugin to programmatically generate documentation pages during the build" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea"}, + {file = "mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc"}, +] [package.dependencies] mkdocs = ">=1.0.3" @@ -1383,9 +2380,12 @@ mkdocs = ">=1.0.3" name = "mkdocs-git-authors-plugin" version = "0.7.0" description = "Mkdocs plugin to display git authors of a page" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mkdocs-git-authors-plugin-0.7.0.tar.gz", hash = "sha256:087b63090ebbf6b93f20d8b8e5fbac8e8b140e2107e432ca2ac8dd1d3a1000f5"}, + {file = "mkdocs_git_authors_plugin-0.7.0-py3-none-any.whl", hash = "sha256:cc469208f98e9db08561eac08a9d8ccd0209a60ee5bd0e3e94b6840a5abc54b6"}, +] [package.dependencies] mkdocs = ">=1.0" @@ -1394,9 +2394,12 @@ mkdocs = ">=1.0" name = "mkdocs-jupyter" version = "0.24.1" description = "Use Jupyter in mkdocs websites" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_jupyter-0.24.1-py3-none-any.whl", hash = "sha256:759833c7d1528ae2d6337342786be7bc1e2235b0b98e9326427d4cf8d4eebee0"}, + {file = "mkdocs_jupyter-0.24.1.tar.gz", hash = "sha256:9677037fb7e931268f3df7599fc0828c261247df3d1575bced320ba8b7d1d46d"}, +] [package.dependencies] jupytext = ">1.13.8,<2" @@ -1412,9 +2415,12 @@ test = ["pytest", "pytest-cov"] name = "mkdocs-literate-nav" version = "0.6.0" description = "MkDocs plugin to specify the navigation in Markdown instead of YAML" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_literate_nav-0.6.0-py3-none-any.whl", hash = "sha256:8c1b84714e5974da5e44e011ec0069275ae7647270c13a679662cf6ffce675a4"}, + {file = "mkdocs_literate_nav-0.6.0.tar.gz", hash = "sha256:81ccbea18163ae8e10bd0bd39237fe70c32a1f2dff6c170779f5d52dd98a0470"}, +] [package.dependencies] mkdocs = ">=1.0.3" @@ -1423,9 +2429,12 @@ mkdocs = ">=1.0.3" name = "mkdocs-material" version = "9.1.11" description = "Documentation that simply works" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_material-9.1.11-py3-none-any.whl", hash = "sha256:fbc86d50ec2cf34d40d5c4365780f290ceedde23f1a0704323b34e7f16b0c0dd"}, + {file = "mkdocs_material-9.1.11.tar.gz", hash = "sha256:f5d473eb79d6640a5e668d4b2ab5b9de5e76ae0a0e2d864112df0cfe9016dc1d"}, +] [package.dependencies] colorama = ">=0.4" @@ -1442,17 +2451,23 @@ requests = ">=2.26" name = "mkdocs-material-extensions" version = "1.1.1" description = "Extension pack for Python Markdown and MkDocs Material." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, + {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, +] [[package]] name = "mkdocstrings" version = "0.21.2" description = "Automatic documentation from sources, for MkDocs." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocstrings-0.21.2-py3-none-any.whl", hash = "sha256:949ef8da92df9d692ca07be50616459a6b536083a25520fd54b00e8814ce019b"}, + {file = "mkdocstrings-0.21.2.tar.gz", hash = "sha256:304e56a2e90595708a38a13a278e538a67ad82052dd5c8b71f77a604a4f3d911"}, +] [package.dependencies] Jinja2 = ">=2.11.1" @@ -1473,9 +2488,12 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] name = "mkdocstrings-python" version = "1.0.0" description = "A Python handler for mkdocstrings." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocstrings_python-1.0.0-py3-none-any.whl", hash = "sha256:c59d67009a7a85172f4da990d8523e95606b6a1ff93a22a2351ad3b5f8cafed1"}, + {file = "mkdocstrings_python-1.0.0.tar.gz", hash = "sha256:b89d849df990204f909d5452548b6936a185f912da06208a93909bebe25d6e67"}, +] [package.dependencies] griffe = ">=0.24" @@ -1485,9 +2503,11 @@ mkdocstrings = ">=0.20" name = "mknotebooks" version = "0.7.1" description = "Plugin for mkdocs to generate markdown documents from jupyter notebooks." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mknotebooks-0.7.1-py3-none-any.whl", hash = "sha256:e2fa000b706683fc56b93adada7190a0da22ad85c4f1bfd5c4468cc3552b78e5"}, +] [package.dependencies] gitpython = "*" @@ -1500,9 +2520,12 @@ nbconvert = ">=6.0.0" name = "mktestdocs" version = "0.2.1" description = "" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mktestdocs-0.2.1-py2.py3-none-any.whl", hash = "sha256:55ad757e83227d5ba217eb285b8e44dc490601c4bbef52bc3331fea4510b72ec"}, + {file = "mktestdocs-0.2.1.tar.gz", hash = "sha256:44142b98223f02c7ba4629790d9ee83031fd4d8855577c6fbfc23103421d3872"}, +] [package.extras] test = ["pytest (>=4.0.2)"] @@ -1511,9 +2534,27 @@ test = ["pytest (>=4.0.2)"] name = "ml-dtypes" version = "0.1.0" description = "" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "ml_dtypes-0.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:377f2d5cfbf809b59188e0bfda4a0774e658541f575b637fee4850d99c2f9fdc"}, + {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87aa1cf83d41fed5a40fc27ee57ac4c1bf904e940f082531d3d58f1c318b5928"}, + {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee8ea629b8e3e20c6649852c1b9deacfa13384ab9337f2c9e717e401d102f23"}, + {file = "ml_dtypes-0.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad765159ac6c18d5ee7d325fcf34d3106a9d9d7a49713d998f5cfa330a1459b4"}, + {file = "ml_dtypes-0.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b9c5578dffd85637a7dd437192de18bc1a14eb6ba7d53ef40de3f84c51c789e5"}, + {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e8518c8fd2c38729f020125f39ef07b045f5c16d0846320c7252d7773285ee"}, + {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99fab8262d175c49bf1655c229244f301274e8289449c350ba4d5b95ade07d9a"}, + {file = "ml_dtypes-0.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8de9bbf5bed587a1166699447ea14d1e8fe66d4e812811e37bf2f4d988475476"}, + {file = "ml_dtypes-0.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a29fbf128583673eca0f43def1dbe77e02c1e8b8a8331db2877bbb57d091ef11"}, + {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273c306db846005b83a98c9c7ec3dc8fa20e8f11c3772c8e8c20cc12d8abfd4b"}, + {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41b6beeaea47e2466b94068664c9a45b2a65dd023aa4e5deeb5a73303661344e"}, + {file = "ml_dtypes-0.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2de6c81b0da398d54aabdd7de599f2dfc43e30b65d9fad379a69f4cc4ae165d3"}, + {file = "ml_dtypes-0.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:77970beeb3cf6ac559c4b6b393f24778a5abd34fafbaad82d5a0d17d0f148936"}, + {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffb7882dd46399217dc54f37affc899e0a29a4cfb63e5bf733ac0baf4a179c77"}, + {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5c9fe086756fbc1bf51296431d64429536093cf6e2ba592e042d7fc07c8514"}, + {file = "ml_dtypes-0.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9218175b06764b8ddc95cb18d11a6c4b48a4b103a31c9ea2b2c3cd0cfc369f8"}, + {file = "ml_dtypes-0.1.0.tar.gz", hash = "sha256:c1fc0afe63ce99069f9d7e0693a61cfd0aea90241fc3821af9953d0c11f4048a"}, +] [package.dependencies] numpy = [ @@ -1526,2563 +2567,12 @@ numpy = [ dev = ["absl-py", "pyink", "pylint (>=2.6.0)", "pytest", "pytest-xdist"] [[package]] -name = "msgpack" -version = "1.0.5" -description = "MessagePack serializer" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "multidict" -version = "6.0.4" -description = "multidict implementation" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "munch" -version = "2.5.0" -description = "A dot-accessible dictionary (a la JavaScript objects)" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -six = "*" - -[package.extras] -testing = ["astroid (>=1.5.3,<1.6.0)", "astroid (>=2.0)", "coverage", "pylint (>=1.7.2,<1.8.0)", "pylint (>=2.3.1,<2.4.0)", "pytest"] -yaml = ["PyYAML (>=5.1.0)"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "nbclient" -version = "0.7.4" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "dev" -optional = false -python-versions = ">=3.7.0" - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" -nbformat = ">=5.1" -traitlets = ">=5.3" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbconvert" -version = "7.4.0" -description = "Converting Jupyter Notebooks" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -beautifulsoup4 = "*" -bleach = "*" -defusedxml = "*" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} -jinja2 = ">=3.0" -jupyter-core = ">=4.7" -jupyterlab-pygments = "*" -markupsafe = ">=2.0" -mistune = ">=2.0.3,<3" -nbclient = ">=0.5.0" -nbformat = ">=5.1" -packaging = "*" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -tinycss2 = "*" -traitlets = ">=5.0" - -[package.extras] -all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] -docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert[qtpng]"] -qtpng = ["pyqtwebengine (>=5.15)"] -serve = ["tornado (>=6.1)"] -test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] -webpdf = ["pyppeteer (>=1,<1.1)"] - -[[package]] -name = "nbformat" -version = "5.8.0" -description = "The Jupyter Notebook format" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -fastjsonschema = "*" -jsonschema = ">=2.6" -jupyter-core = "*" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - -[[package]] -name = "nbstripout" -version = "0.6.1" -description = "Strips outputs from Jupyter and IPython notebooks" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -nbformat = "*" - -[[package]] -name = "nest-asyncio" -version = "1.5.6" -description = "Patch asyncio to allow nested event loops" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "networkx" -version = "3.1" -description = "Python package for creating and manipulating graphs and networks" -category = "dev" -optional = false -python-versions = ">=3.8" - -[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 = "nodeenv" -version = "1.7.0" -description = "Node.js virtual environment builder" -category = "dev" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" - -[package.dependencies] -setuptools = "*" - -[[package]] -name = "nox" -version = "2022.11.21" -description = "Flexible test automation." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -argcomplete = ">=1.9.4,<3.0" -colorlog = ">=2.6.1,<7.0.0" -packaging = ">=20.9" -virtualenv = ">=14" - -[package.extras] -tox-to-nox = ["jinja2", "tox"] - -[[package]] -name = "numpy" -version = "1.24.3" -description = "Fundamental package for array computing in Python" -category = "main" -optional = false -python-versions = ">=3.8" - -[[package]] -name = "opt-einsum" -version = "3.3.0" -description = "Optimizing numpys einsum function" -category = "main" -optional = false -python-versions = ">=3.5" - -[package.dependencies] -numpy = ">=1.7" - -[package.extras] -docs = ["numpydoc", "sphinx (==1.2.3)", "sphinx-rtd-theme", "sphinxcontrib-napoleon"] -tests = ["pytest", "pytest-cov", "pytest-pep8"] - -[[package]] -name = "optax" -version = "0.1.5" -description = "A gradient processing and optimisation library in JAX." -category = "main" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -absl-py = ">=0.7.1" -chex = ">=0.1.5" -jax = ">=0.1.55" -jaxlib = ">=0.1.37" -numpy = ">=1.18.0" - -[[package]] -name = "orbax-checkpoint" -version = "0.2.2" -description = "Orbax Checkpoint" -category = "main" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -absl-py = "*" -cached_property = "*" -etils = "*" -importlib_resources = "*" -jax = ">=0.4.8" -jaxlib = "*" -msgpack = "*" -nest_asyncio = "*" -numpy = "*" -pyyaml = "*" -tensorstore = ">=0.1.35" -typing_extensions = "*" - -[package.extras] -dev = ["flax", "pytest", "pytest-xdist"] - -[[package]] -name = "packaging" -version = "23.1" -description = "Core utilities for Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "pandas" -version = "1.5.3" -description = "Powerful data structures for data analysis, time series, and statistics" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, -] -python-dateutil = ">=2.8.1" -pytz = ">=2020.1" - -[package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] - -[[package]] -name = "pandocfilters" -version = "1.5.0" -description = "Utilities for writing pandoc filters in python" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pathlib2" -version = "2.3.7.post1" -description = "Object-oriented filesystem paths" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -six = "*" - -[[package]] -name = "pathspec" -version = "0.11.1" -description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pillow" -version = "9.5.0" -description = "Python Imaging Library (Fork)" -category = "dev" -optional = false -python-versions = ">=3.7" - -[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 = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "planetary-computer" -version = "0.5.1" -description = "Planetary Computer SDK for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -click = ">=7.1" -pydantic = {version = ">=1.7.3", extras = ["dotenv"]} -pystac = ">=1.0.0" -pystac-client = ">=0.2.0" -pytz = ">=2020.5" -requests = ">=2.25.1" - -[package.extras] -adlfs = ["adlfs"] -azure = ["azure-storage-blob"] -dev = ["black", "flake8", "mypy", "pytest", "responses", "setuptools", "types-requests"] - -[[package]] -name = "platformdirs" -version = "3.5.1" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] - -[[package]] -name = "pluggy" -version = "1.0.0" -description = "plugin and hook calling mechanisms for python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "plum-dispatch" -version = "2.1.0" -description = "Multiple dispatch in Python" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -beartype = "*" - -[package.extras] -dev = ["black (==22.10.0)", "build", "coveralls", "ghp-import", "ipython", "jupyter-book", "numpy", "pre-commit", "pytest (>=6)", "pytest-cov", "tox", "wheel"] - -[[package]] -name = "pre-commit" -version = "3.3.1" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "prompt-toolkit" -version = "3.0.38" -description = "Library for building powerful interactive command lines in Python" -category = "dev" -optional = false -python-versions = ">=3.7.0" - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "5.9.5" -description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -category = "dev" -optional = false -python-versions = "*" - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pybtex" -version = "0.24.0" -description = "A BibTeX-compatible bibliography processor in Python" -category = "dev" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" - -[package.dependencies] -latexcodec = ">=1.0.4" -PyYAML = ">=3.01" -six = "*" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pydantic" -version = "1.10.7" -description = "Data validation and settings management using python type hints" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pydocstyle" -version = "6.3.0" -description = "Python docstring style checker" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -snowballstemmer = ">=2.2.0" - -[package.extras] -toml = ["tomli (>=1.2.3)"] - -[[package]] -name = "pygments" -version = "2.15.1" -description = "Pygments is a syntax highlighting package written in Python." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -plugins = ["importlib-metadata"] - -[[package]] -name = "pylint" -version = "2.17.4" -description = "python code static checker" -category = "dev" -optional = false -python-versions = ">=3.7.2" - -[package.dependencies] -astroid = ">=2.15.4,<=2.17.0-dev0" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, -] -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.8" -platformdirs = ">=2.2.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -tomlkit = ">=0.10.1" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -spelling = ["pyenchant (>=3.2,<4.0)"] -testutils = ["gitpython (>3)"] - -[[package]] -name = "pymdown-extensions" -version = "9.11" -description = "Extension pack for Python Markdown." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -markdown = ">=3.2" -pyyaml = "*" - -[[package]] -name = "pypandoc" -version = "1.11" -description = "Thin wrapper for pandoc." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" -optional = false -python-versions = ">=3.6.8" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyproj" -version = "3.5.0" -description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -certifi = "*" - -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "pystac" -version = "1.7.3" -description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -python-dateutil = ">=2.7.0" - -[package.extras] -orjson = ["orjson (>=3.5)"] -urllib3 = ["urllib3 (>=1.26)"] -validation = ["jsonschema (>=4.0.1)"] - -[[package]] -name = "pystac-client" -version = "0.6.1" -description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -pystac = ">=1.7.0" -python-dateutil = ">=2.7.0" -requests = ">=2.27.1" - -[package.extras] -validation = ["jsonschema (>=4.5.1)"] - -[[package]] -name = "pytest" -version = "7.3.1" -description = "pytest: simple powerful testing with Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[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", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "4.0.0" -description = "Pytest plugin for measuring coverage." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pytest-pretty" -version = "1.2.0" -description = "pytest plugin for printing summary data as I want it" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -pytest = ">=7" -rich = ">=12" - -[[package]] -name = "pytest-xdist" -version = "3.2.1" -description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -execnet = ">=1.1" -pytest = ">=6.2.0" - -[package.extras] -psutil = ["psutil (>=3.0)"] -setproctitle = ["setproctitle"] -testing = ["filelock"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-dotenv" -version = "1.0.0" -description = "Read key-value pairs from a .env file and set them as environment variables" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.extras] -cli = ["click (>=5.0)"] - -[[package]] -name = "pytkdocs" -version = "0.16.1" -description = "Load Python objects documentation." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -astunparse = {version = ">=1.6", markers = "python_version < \"3.9\""} - -[package.extras] -numpy-style = ["docstring_parser (>=0.7)"] - -[[package]] -name = "pytz" -version = "2023.3" -description = "World timezone definitions, modern and historical" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyyaml-env-tag" -version = "0.1" -description = "A custom YAML tag for referencing environment variables in YAML files. " -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyyaml = "*" - -[[package]] -name = "pyzmq" -version = "25.0.2" -description = "Python bindings for 0MQ" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "rasterio" -version = "1.3.6" -description = "Fast and direct raster I/O for use with Numpy and SciPy" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -affine = "*" -attrs = "*" -certifi = "*" -click = ">=4.0" -click-plugins = "*" -cligj = ">=0.5" -numpy = ">=1.18" -setuptools = "*" -snuggs = ">=1.4.1" - -[package.extras] -all = ["boto3 (>=1.2.4)", "ghp-import", "hypothesis", "ipython (>=2.0)", "matplotlib", "numpydoc", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely", "sphinx", "sphinx-rtd-theme"] -docs = ["ghp-import", "numpydoc", "sphinx", "sphinx-rtd-theme"] -ipython = ["ipython (>=2.0)"] -plot = ["matplotlib"] -s3 = ["boto3 (>=1.2.4)"] -test = ["boto3 (>=1.2.4)", "hypothesis", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely"] - -[[package]] -name = "regex" -version = "2023.5.5" -description = "Alternative regular expression module, to replace re." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "requests" -version = "2.30.0" -description = "Python HTTP for Humans." -category = "dev" -optional = false -python-versions = ">=3.7" - -[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 = "rich" -version = "13.3.5" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" -optional = false -python-versions = ">=3.7.0" - -[package.dependencies] -markdown-it-py = ">=2.2.0,<3.0.0" -pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "rioxarray" -version = "0.13.4" -description = "geospatial xarray extension powered by rasterio" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -numpy = ">=1.21" -packaging = "*" -pyproj = ">=2.2" -rasterio = ">=1.1.1" -xarray = ">=0.17" - -[package.extras] -all = ["dask", "mypy", "nbsphinx", "netcdf4", "pre-commit", "pylint", "pytest (>=3.6)", "pytest-cov", "pytest-timeout", "scipy", "sphinx-click", "sphinx-rtd-theme"] -dev = ["dask", "mypy", "nbsphinx", "netcdf4", "pre-commit", "pylint", "pytest (>=3.6)", "pytest-cov", "pytest-timeout", "scipy", "sphinx-click", "sphinx-rtd-theme"] -doc = ["nbsphinx", "sphinx-click", "sphinx-rtd-theme"] -interp = ["scipy"] -test = ["dask", "netcdf4", "pytest (>=3.6)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "ruff" -version = "0.0.259" -description = "An extremely fast Python linter, written in Rust." -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "scikit-learn" -version = "1.2.2" -description = "A set of python modules for machine learning and data mining" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -joblib = ">=1.1.1" -numpy = ">=1.17.3" -scipy = ">=1.3.2" -threadpoolctl = ">=2.0.0" - -[package.extras] -benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] -tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] - -[[package]] -name = "scipy" -version = "1.10.1" -description = "Fundamental algorithms for scientific computing in Python" -category = "main" -optional = false -python-versions = "<3.12,>=3.8" - -[package.dependencies] -numpy = ">=1.19.5,<1.27.0" - -[package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "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 = "seaborn" -version = "0.12.2" -description = "Statistical data visualization" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -matplotlib = ">=3.1,<3.6.1 || >3.6.1" -numpy = ">=1.17,<1.24.0 || >1.24.0" -pandas = ">=0.25" - -[package.extras] -dev = ["flake8", "flit", "mypy", "pandas-stubs", "pre-commit", "pytest", "pytest-cov", "pytest-xdist"] -docs = ["ipykernel", "nbconvert", "numpydoc", "pydata_sphinx_theme (==0.10.0rc2)", "pyyaml", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] -stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] - -[[package]] -name = "setuptools" -version = "67.7.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "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 (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "setuptools-scm" -version = "7.1.0" -description = "the blessed package to manage your versions by scm tags" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -packaging = ">=20.0" -setuptools = "*" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} -typing-extensions = "*" - -[package.extras] -test = ["pytest (>=6.2)", "virtualenv (>20)"] -toml = ["setuptools (>=42)"] - -[[package]] -name = "shapely" -version = "2.0.1" -description = "Manipulation and analysis of geometric objects" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -numpy = ">=1.14" - -[package.extras] -docs = ["matplotlib", "numpydoc (>=1.1.0,<1.2.0)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "simple-pytree" -version = "0.1.7" -description = "" -category = "main" -optional = false -python-versions = ">=3.8,<3.12" - -[package.dependencies] -jax = "*" -jaxlib = "*" - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "smmap" -version = "5.0.0" -description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "snuggs" -version = "1.4.7" -description = "Snuggs are s-expressions for Numpy" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -numpy = "*" -pyparsing = ">=2.1.6" - -[package.extras] -test = ["hypothesis", "pytest"] - -[[package]] -name = "soupsieve" -version = "2.4.1" -description = "A modern CSS selector implementation for Beautiful Soup." -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "stack-data" -version = "0.6.2" -description = "Extract data from python stack frames and tracebacks for informative displays" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - -[[package]] -name = "tabulate" -version = "0.9.0" -description = "Pretty-print tabular data" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -widechars = ["wcwidth"] - -[[package]] -name = "tensorflow-probability" -version = "0.19.0" -description = "Probabilistic modeling and statistical inference in TensorFlow" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -absl-py = "*" -cloudpickle = ">=1.3" -decorator = "*" -dm-tree = "*" -gast = ">=0.3.2" -numpy = ">=1.13.3" -six = ">=1.10.0" - -[package.extras] -jax = ["jax", "jaxlib"] -tfds = ["tensorflow-datasets (>=2.2.0)"] - -[[package]] -name = "tensorstore" -version = "0.1.36" -description = "Read and write large, multi-dimensional arrays" -category = "main" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -numpy = ">=1.16.0" - -[[package]] -name = "threadpoolctl" -version = "3.1.0" -description = "threadpoolctl" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "tinycss2" -version = "1.2.1" -description = "A tiny CSS parser" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "tomlkit" -version = "0.11.8" -description = "Style preserving TOML library" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "toolz" -version = "0.12.0" -description = "List processing tools and functional utilities" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "tornado" -version = "6.3.1" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "dev" -optional = false -python-versions = ">= 3.8" - -[[package]] -name = "tqdm" -version = "4.65.0" -description = "Fast, Extensible Progress Meter" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["py-make (>=0.1.0)", "twine", "wheel"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "traitlets" -version = "5.9.0" -description = "Traitlets Python configuration system" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] - -[[package]] -name = "typeguard" -version = "3.0.2" -description = "Run-time type checker for Python" -category = "main" -optional = false -python-versions = ">=3.7.4" - -[package.dependencies] -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} -typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["mypy (>=0.991)", "pytest (>=7)"] - -[[package]] -name = "typing-extensions" -version = "4.5.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "uc-micro-py" -version = "1.0.2" -description = "Micro subset of unicode data files for linkify-it-py projects." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["coverage", "pytest", "pytest-cov"] - -[[package]] -name = "urllib3" -version = "2.0.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" -optional = false -python-versions = ">=3.7" - -[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 = "validators" -version = "0.20.0" -description = "Python Data Validation for Humans™." -category = "dev" -optional = false -python-versions = ">=3.4" - -[package.dependencies] -decorator = ">=3.4.0" - -[package.extras] -test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] - -[[package]] -name = "virtualenv" -version = "20.23.0" -description = "Virtual Python Environment builder" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.11,<4" -platformdirs = ">=3.2,<4" - -[package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] - -[[package]] -name = "watchdog" -version = "3.0.0" -description = "Filesystem events monitoring" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - -[[package]] -name = "watermark" -version = "2.3.1" -description = "IPython magic function to print date/time stamps and various system information." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -ipython = "*" - -[[package]] -name = "wcwidth" -version = "0.2.6" -description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "wheel" -version = "0.40.0" -description = "A built-package format for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pytest (>=6.0.0)"] - -[[package]] -name = "widgetsnbextension" -version = "4.0.7" -description = "Jupyter interactive widgets for Jupyter Notebook" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "wrapt" -version = "1.15.0" -description = "Module for decorators, wrappers and monkey patching." -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "xarray" -version = "2023.1.0" -description = "N-D labeled arrays and datasets in Python" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -numpy = ">=1.20" -packaging = ">=21.3" -pandas = ">=1.3" - -[package.extras] -accel = ["bottleneck", "flox", "numbagg", "scipy"] -complete = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "matplotlib", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scipy", "seaborn", "zarr"] -docs = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "ipykernel", "ipython", "jupyter-client", "matplotlib", "nbsphinx", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scanpydoc", "scipy", "seaborn", "sphinx-autosummary-accessors", "sphinx-rtd-theme", "zarr"] -io = ["cfgrib", "cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "rasterio", "scipy", "zarr"] -parallel = ["dask[complete]"] -viz = ["matplotlib", "nc-time-axis", "seaborn"] - -[[package]] -name = "xdoctest" -version = "1.1.1" -description = "A rewrite of the builtin doctest module" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -six = "*" - -[package.extras] -all = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "codecov", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "pytest", "pytest", "pytest", "pytest-cov", "six", "tomli", "typing"] -all-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "codecov (==2.0.15)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "six (==1.11.0)", "tomli (==0.2.0)", "typing (==3.7.4)"] -colors = ["Pygments", "Pygments", "colorama"] -jupyter = ["IPython", "IPython", "attrs", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert"] -optional = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "tomli"] -optional-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "tomli (==0.2.0)"] -runtime-strict = ["six (==1.11.0)"] -tests = ["codecov", "pytest", "pytest", "pytest", "pytest-cov", "typing"] -tests-binary = ["cmake", "cmake", "ninja", "ninja", "pybind11", "pybind11", "scikit-build", "scikit-build"] -tests-binary-strict = ["cmake (==3.21.2)", "cmake (==3.25.0)", "ninja (==1.10.2)", "ninja (==1.11.1)", "pybind11 (==2.10.3)", "pybind11 (==2.7.1)", "scikit-build (==0.11.1)", "scikit-build (==0.16.1)"] -tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "typing (==3.7.4)"] - -[[package]] -name = "yarl" -version = "1.9.2" -description = "Yet another URL library" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" - -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[metadata] -lock-version = "1.1" -python-versions = ">=3.8,<3.12" -content-hash = "4ed9c80c1a846cafdd3755f77a6a63068ac78668b5963dc92940a3e1f17c038d" - -[metadata.files] -absl-py = [ - {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, - {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, -] -absolufy-imports = [ - {file = "absolufy_imports-0.3.1-py2.py3-none-any.whl", hash = "sha256:49bf7c753a9282006d553ba99217f48f947e3eef09e18a700f8a82f75dc7fc5c"}, - {file = "absolufy_imports-0.3.1.tar.gz", hash = "sha256:c90638a6c0b66826d1fb4880ddc20ef7701af34192c94faf40b95d32b59f9793"}, -] -affine = [ - {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, - {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, -] -aiohttp = [ - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"}, - {file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"}, - {file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"}, - {file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"}, - {file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"}, - {file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"}, - {file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"}, - {file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"}, - {file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"}, - {file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"}, - {file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"}, - {file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"}, -] -aiosignal = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, -] -appnope = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] -argcomplete = [ - {file = "argcomplete-2.1.2-py3-none-any.whl", hash = "sha256:4ba9cdaa28c361d251edce884cd50b4b1215d65cdc881bd204426cdde9f52731"}, - {file = "argcomplete-2.1.2.tar.gz", hash = "sha256:fc82ef070c607b1559b5c720529d63b54d9dcf2dcfc2632b10e6372314a34457"}, -] -astroid = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, -] -asttokens = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, -] -astunparse = [ - {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, - {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -attrs = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -beartype = [ - {file = "beartype-0.13.1-py3-none-any.whl", hash = "sha256:c3097b487e57bc278f1b55da8863b704b2a786c46483a6d3df39ab6fe2523d80"}, - {file = "beartype-0.13.1.tar.gz", hash = "sha256:2903947a8a1eb6030264e30108aa72cb1a805cfc9050c0f4014c4aed3a17a00b"}, -] -beautifulsoup4 = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, -] -black = [ - {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, - {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, - {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, - {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, - {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, - {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, - {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, - {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, - {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, - {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, - {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, - {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, - {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, - {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, -] -blackjax = [ - {file = "blackjax-0.9.6-py3-none-any.whl", hash = "sha256:d1c20dd15a63944a7b5c835bac4900aadf8630bedb0d7e51ab7fc63255eb0dd7"}, - {file = "blackjax-0.9.6.tar.gz", hash = "sha256:fb708f183d714750feb475fb87b8162fc1641309f30ee42fd38a5dec82733868"}, -] -bleach = [ - {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, - {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, -] -cached-property = [ - {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, - {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, -] -certifi = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, -] -cffi = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] -cfgv = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, -] -charset-normalizer = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, -] -chex = [ - {file = "chex-0.1.7-py3-none-any.whl", hash = "sha256:9f583015303b1205443843c0b55849bb287f1dfdbd22d9907b1ebb04f964d93e"}, - {file = "chex-0.1.7.tar.gz", hash = "sha256:74ed49799ac4d229881456d468136f1b19a9f9839e3de72b058824e2a4f4dedd"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -click-plugins = [ - {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, - {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, -] -cligj = [ - {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, - {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, -] -cloudpickle = [ - {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, - {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, -] -codespell = [ - {file = "codespell-2.2.4-py3-none-any.whl", hash = "sha256:7d984b8130108e6f82524b7d09f8b7bf2fb1e398c5d4b37d9e2bd310145b3e29"}, - {file = "codespell-2.2.4.tar.gz", hash = "sha256:0b4620473c257d9cde1ff8998b26b2bb209a35c2b7489f5dc3436024298ce83a"}, -] -colorama = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -colorlog = [ - {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, - {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, -] -comm = [ - {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"}, - {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"}, -] -contourpy = [ - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"}, - {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"}, - {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"}, - {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"}, - {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"}, - {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"}, - {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"}, - {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"}, - {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"}, - {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"}, -] -coverage = [ - {file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"}, - {file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"}, - {file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"}, - {file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"}, - {file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"}, - {file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"}, - {file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"}, - {file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"}, - {file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"}, - {file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"}, - {file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"}, - {file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"}, - {file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"}, - {file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"}, - {file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"}, - {file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"}, - {file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"}, - {file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"}, - {file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"}, - {file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"}, - {file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"}, -] -cycler = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, -] -debugpy = [ - {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"}, - {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"}, - {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"}, - {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"}, - {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"}, - {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"}, - {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"}, - {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"}, - {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"}, - {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"}, - {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"}, - {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"}, - {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"}, - {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"}, - {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"}, - {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"}, - {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"}, - {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"}, -] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -defusedxml = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] -dill = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, -] -distlib = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, -] -dm-tree = [ - {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, - {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, - {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, - {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, - {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, - {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, - {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, -] -etils = [ - {file = "etils-1.2.0-py3-none-any.whl", hash = "sha256:c6585069b387fdbeed6a2c571b8bcf312ecdb577c95065461e5fad9ed1973989"}, - {file = "etils-1.2.0.tar.gz", hash = "sha256:29d369e2dcf43960d9ee338330579d04badd606c88f015f4e1a38d3adbe446d8"}, -] -exceptiongroup = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, -] -execnet = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, -] -executing = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, -] -fastjsonschema = [ - {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, - {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, -] -fastprogress = [ - {file = "fastprogress-1.0.3-py3-none-any.whl", hash = "sha256:6dfea88f7a4717b0a8d6ee2048beae5dbed369f932a368c5dd9caff34796f7c5"}, - {file = "fastprogress-1.0.3.tar.gz", hash = "sha256:7a17d2b438890f838c048eefce32c4ded47197ecc8ea042cecc33d3deb8022f5"}, -] -filelock = [ - {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, - {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, -] -fiona = [ - {file = "Fiona-1.9.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0e9141bdb8031419ed2f04c6da02ae12c3044a81987065e05ff40f39cc35e042"}, - {file = "Fiona-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c0251a57305e6bea3f0a8e8306c0bd05e2b0e30b8a294d7bdc429d5fceca68d"}, - {file = "Fiona-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:894127efde8141bb9383dc4dc890c732f3bfe4d601c3d1020a24fa3c24a8c4a8"}, - {file = "Fiona-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:11ee3d3e6bb5d16f6f1643ffcde7ac4dfa5fbe98a26ce2af05c3c5426ce248d7"}, - {file = "Fiona-1.9.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c99e9bca9e3d6be03a71e9b2f6ba66d446eae9b27df37c1f6b45483b2f215ca0"}, - {file = "Fiona-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a894362c1cf9f33ee931e96cfd4021d3a18f6ccf8c36b87df42a0a494e23545"}, - {file = "Fiona-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0761ff656d07aaef7a7274b74816e16485f0f15e77a962c107cd4a1cfb4757"}, - {file = "Fiona-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:2e61caeabda88ab5fa45db373c2afd6913844b4452c0f2e3e9d924c60bc76fa3"}, - {file = "Fiona-1.9.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:00628c5a3dd7e9bc037ba0487fc3b9f7163107e0a9794bd4c32c471ab65f3a45"}, - {file = "Fiona-1.9.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:95927ddd9afafdb0243bb83bf234557dcdb35bf0e888fd920ff82ffa80f6a53a"}, - {file = "Fiona-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d1064e82a7fed73ce60ce9ce4f65b5a6558fb5b532a13130a17f132ed122ec75"}, - {file = "Fiona-1.9.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:65b096148bfe9a64d87d91ba8e7ff940a5aef8cbffc6738a70e289c6384e1cca"}, - {file = "Fiona-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:38d0d78d4e061592af3441c5962072b0456307246c9c6f412ad38ebef11d2903"}, - {file = "Fiona-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee9b2ec9f0fb4b3798d607a94a5586b403fc27fea06e3e7ac2924c0785d4df61"}, - {file = "Fiona-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:258151f26683a44ed715c09930a42e0b39b3b3444b438ec6e32633f7056740fa"}, - {file = "Fiona-1.9.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:f1fcadad17b00d342532dc51a47128005f8ced01a320fa6b72c8ef669edf3057"}, - {file = "Fiona-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85b6694227ee4e00dfa52c6a9fcc89f1051aaf67df5fbd1faa33fb02c62a6203"}, - {file = "Fiona-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e661deb7a8722839bd27eae74f63f0e480559774cc755598dfa6c51bdf18be3d"}, - {file = "Fiona-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:a57812a584b4a2fb4ffdfaa9135dc38312989f7cd2823ecbd23e11eade5eb7fe"}, - {file = "Fiona-1.9.3.tar.gz", hash = "sha256:60f3789ad9633c3a26acf7cbe39e82e3c7a12562c59af1d599fc3e4e8f7f8f25"}, -] -flax = [ - {file = "flax-0.6.10-py3-none-any.whl", hash = "sha256:8dccc7b84b00ff6f59a36dc0e79f5919498cfeb009a41f8c07f68bf2513198db"}, - {file = "flax-0.6.10.tar.gz", hash = "sha256:e2174a0df7bb4921f29b2cbd33f55ddf6eed161d6df61809fe374a25e473fb2f"}, -] -fonttools = [ - {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"}, - {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"}, -] -frozenlist = [ - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, - {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, - {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, - {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, - {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, - {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, - {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, - {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, - {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, - {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, - {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, -] -fsspec = [ - {file = "fsspec-2023.5.0-py3-none-any.whl", hash = "sha256:51a4ad01a5bb66fcc58036e288c0d53d3975a0df2a5dc59a93b59bade0391f2a"}, - {file = "fsspec-2023.5.0.tar.gz", hash = "sha256:b3b56e00fb93ea321bc9e5d9cf6f8522a0198b20eb24e02774d329e9c6fb84ce"}, -] -gast = [ - {file = "gast-0.5.4-py3-none-any.whl", hash = "sha256:6fc4fa5fa10b72fb8aab4ae58bcb023058386e67b6fa2e3e34cec5c769360316"}, - {file = "gast-0.5.4.tar.gz", hash = "sha256:9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97"}, -] -geopandas = [ - {file = "geopandas-0.12.2-py3-none-any.whl", hash = "sha256:0a470e4bf6f5367e6fd83ab6b40405e0b805c8174665bbcb7c4077ed90202912"}, - {file = "geopandas-0.12.2.tar.gz", hash = "sha256:0acdacddefa176525e4da6d9aeeece225da26055c4becdc6e97cf40fa97c27f4"}, -] -ghp-import = [ - {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, - {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, -] -gitdb = [ - {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, - {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, -] -gitpython = [ - {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, - {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, -] -griffe = [ - {file = "griffe-0.27.4-py3-none-any.whl", hash = "sha256:685350067286229e80a18b8989d6acbd43abdf8b763591221d19c56f4108549e"}, - {file = "griffe-0.27.4.tar.gz", hash = "sha256:088c25fb22f8d1f1add5d3b58a86a3969993181a36ca55b3fa33096a3f3b1a23"}, -] -identify = [ - {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"}, - {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"}, -] -idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] -importlib-metadata = [ - {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, - {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, -] -importlib-resources = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, -] -iniconfig = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] -interrogate = [ - {file = "interrogate-1.5.0-py3-none-any.whl", hash = "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a"}, - {file = "interrogate-1.5.0.tar.gz", hash = "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c"}, -] -ipykernel = [ - {file = "ipykernel-6.23.0-py3-none-any.whl", hash = "sha256:fc886f1dcdc0ec17f277e4d21fd071c857d381adcb04f3f3735d25325ca323c6"}, - {file = "ipykernel-6.23.0.tar.gz", hash = "sha256:bd6f487d9e2744c84f6e667d46462d7647a4c862e70e08282f05a52b9d4b705f"}, -] -ipython = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, -] -ipywidgets = [ - {file = "ipywidgets-8.0.6-py3-none-any.whl", hash = "sha256:a60bf8d2528997e05ac83fd19ea2fbe65f2e79fbe1b2b35779bdfc46c2941dcc"}, - {file = "ipywidgets-8.0.6.tar.gz", hash = "sha256:de7d779f2045d60de9f6c25f653fdae2dba57898e6a1284494b3ba20b6893bb8"}, -] -isort = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] -jax = [ - {file = "jax-0.4.9.tar.gz", hash = "sha256:1ed135cd08f48e4baf10f6eafdb4a4cdae781f9052b5838c09c91a9f4fa75f09"}, -] -jaxlib = [ - {file = "jaxlib-0.4.7-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:63c2890978e8646516db3d8a680b43d2bed8b63543a70556391f589a261bd85f"}, - {file = "jaxlib-0.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c16f922507277d5630e81d9c1a4974366a27aad5230d645d063bc2011564d01"}, - {file = "jaxlib-0.4.7-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:da88382e6487805974cea6facc61ba92b5828a7a1f2dd80f762c487d873a2b47"}, - {file = "jaxlib-0.4.7-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:022b216036c009989d4c0683538820c19247215bb99fdd35c7bf32838d596be6"}, - {file = "jaxlib-0.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d0f1d3b6ef6c68013898cca958ab1507d6809b523275037efbdb9aaaaab158ba"}, - {file = "jaxlib-0.4.7-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:0ae7178c33460822d9d8d03718cba395e02e6bac2402709c35826c94f0c9cc7b"}, - {file = "jaxlib-0.4.7-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:ea07605e37d2b4e25f3c639e0d22ab4605fbc1a10ea918fd14ce09077bdaffb6"}, - {file = "jaxlib-0.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:48b85d3c8923b1619ddf8cbf14c4e4daf6919796d8aa9d006ce2a085e8202930"}, - {file = "jaxlib-0.4.7-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a860f2990c97bee5ffcdbb5111751591e5e7a66d5e32b4f6d9e6aa14ac82bf27"}, - {file = "jaxlib-0.4.7-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c78dc2b6fa1c92ead137a23d1bd3e10d04c58b268e77eca811502abac05b2b19"}, - {file = "jaxlib-0.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1f3726e374d0d6fcc14da540b71b758d37356c6726f0f4b48e2f5530a5f8769"}, - {file = "jaxlib-0.4.7-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:d4629205dbe342153941db5f69c4a1bfe35fd8d2947aebe34f4dff3771d3fff7"}, -] -jaxopt = [ - {file = "jaxopt-0.6-py3-none-any.whl", hash = "sha256:69af71c39969e9e5fa54bd50cbab3e18f6c32659d92e1bf56912a24c8ad0fca6"}, - {file = "jaxopt-0.6.tar.gz", hash = "sha256:19df9cb745ee39fa27f9ba4f01bbec5b0e3a8a1f60320aff553131a5f152c9fa"}, -] -jaxtyping = [ - {file = "jaxtyping-0.2.19-py3-none-any.whl", hash = "sha256:651352032799d422987e783fd1b77699b53c3bb28ffa644bbca5f75ec4fbb843"}, - {file = "jaxtyping-0.2.19.tar.gz", hash = "sha256:21ff4c3caec6781cadfe980b019dde856c1011e17d11dfe8589298040056325a"}, -] -jedi = [ - {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, - {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, -] -jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] -joblib = [ - {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"}, - {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"}, -] -jsonschema = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, -] -jupyter-client = [ - {file = "jupyter_client-8.2.0-py3-none-any.whl", hash = "sha256:b18219aa695d39e2ad570533e0d71fb7881d35a873051054a84ee2a17c4b7389"}, - {file = "jupyter_client-8.2.0.tar.gz", hash = "sha256:9fe233834edd0e6c0aa5f05ca2ab4bdea1842bfd2d8a932878212fc5301ddaf0"}, -] -jupyter-core = [ - {file = "jupyter_core-5.3.0-py3-none-any.whl", hash = "sha256:d4201af84559bc8c70cead287e1ab94aeef3c512848dde077b7684b54d67730d"}, - {file = "jupyter_core-5.3.0.tar.gz", hash = "sha256:6db75be0c83edbf1b7c9f91ec266a9a24ef945da630f3120e1a0046dc13713fc"}, -] -jupyterlab-pygments = [ - {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, - {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, -] -jupyterlab-widgets = [ - {file = "jupyterlab_widgets-3.0.7-py3-none-any.whl", hash = "sha256:c73f8370338ec19f1bec47254752d6505b03601cbd5a67e6a0b184532f73a459"}, - {file = "jupyterlab_widgets-3.0.7.tar.gz", hash = "sha256:c3a50ed5bf528a0c7a869096503af54702f86dda1db469aee1c92dc0c01b43ca"}, -] -jupytext = [ - {file = "jupytext-1.14.5-py3-none-any.whl", hash = "sha256:a5dbe60d0ea158bbf82c2bce74aba8d0c220ad7edcda09e017c5eba229b34dc8"}, - {file = "jupytext-1.14.5.tar.gz", hash = "sha256:976e66be8056459a2067e0ec3ff68cc31e00c31895faf9eb893022d319e8f5b4"}, -] -kiwisolver = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, -] -latexcodec = [ - {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, - {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] -linkify-it-py = [ - {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, - {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, -] -markdown = [ - {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, - {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, -] -markdown-it-py = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, -] -markdown-katex = [ - {file = "markdown-katex-202112.1034.tar.gz", hash = "sha256:27892f4cdd6763816f00e4187d0475500697c090aba16630ec4803a6564bf810"}, - {file = "markdown_katex-202112.1034-py2.py3-none-any.whl", hash = "sha256:9ccc5b4b37db7592cc3ea113d763fafe9ffd1b1587e2c217d6145e44a10b4f6d"}, -] -markupsafe = [ - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, - {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, -] -matplotlib = [ - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, - {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, - {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, - {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, - {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, - {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, - {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, - {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, - {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, - {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, -] -matplotlib-inline = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, -] -mccabe = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] -mdit-py-plugins = [ - {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, - {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, -] -mdurl = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] -mdx-truly-sane-lists = [ - {file = "mdx_truly_sane_lists-1.3-py3-none-any.whl", hash = "sha256:b9546a4c40ff8f1ab692f77cee4b6bfe8ddf9cccf23f0a24e71f3716fe290a37"}, - {file = "mdx_truly_sane_lists-1.3.tar.gz", hash = "sha256:b661022df7520a1e113af7c355c62216b384c867e4f59fb8ee7ad511e6e77f45"}, -] -mergedeep = [ - {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, - {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, -] -mistune = [ - {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, - {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, -] -mkdocs = [ - {file = "mkdocs-1.4.3-py3-none-any.whl", hash = "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd"}, - {file = "mkdocs-1.4.3.tar.gz", hash = "sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57"}, -] -mkdocs-autorefs = [ - {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, - {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, -] -mkdocs-bibtex = [ - {file = "mkdocs-bibtex-2.8.16.tar.gz", hash = "sha256:d4f4d284a72a7a943ab427fff58e74409fb26eb0536f89f202c891fdda2eb50a"}, -] -mkdocs-gen-files = [ - {file = "mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea"}, - {file = "mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc"}, -] -mkdocs-git-authors-plugin = [ - {file = "mkdocs-git-authors-plugin-0.7.0.tar.gz", hash = "sha256:087b63090ebbf6b93f20d8b8e5fbac8e8b140e2107e432ca2ac8dd1d3a1000f5"}, - {file = "mkdocs_git_authors_plugin-0.7.0-py3-none-any.whl", hash = "sha256:cc469208f98e9db08561eac08a9d8ccd0209a60ee5bd0e3e94b6840a5abc54b6"}, -] -mkdocs-jupyter = [ - {file = "mkdocs_jupyter-0.24.1-py3-none-any.whl", hash = "sha256:759833c7d1528ae2d6337342786be7bc1e2235b0b98e9326427d4cf8d4eebee0"}, - {file = "mkdocs_jupyter-0.24.1.tar.gz", hash = "sha256:9677037fb7e931268f3df7599fc0828c261247df3d1575bced320ba8b7d1d46d"}, -] -mkdocs-literate-nav = [ - {file = "mkdocs_literate_nav-0.6.0-py3-none-any.whl", hash = "sha256:8c1b84714e5974da5e44e011ec0069275ae7647270c13a679662cf6ffce675a4"}, - {file = "mkdocs_literate_nav-0.6.0.tar.gz", hash = "sha256:81ccbea18163ae8e10bd0bd39237fe70c32a1f2dff6c170779f5d52dd98a0470"}, -] -mkdocs-material = [ - {file = "mkdocs_material-9.1.11-py3-none-any.whl", hash = "sha256:fbc86d50ec2cf34d40d5c4365780f290ceedde23f1a0704323b34e7f16b0c0dd"}, - {file = "mkdocs_material-9.1.11.tar.gz", hash = "sha256:f5d473eb79d6640a5e668d4b2ab5b9de5e76ae0a0e2d864112df0cfe9016dc1d"}, -] -mkdocs-material-extensions = [ - {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, - {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, -] -mkdocstrings = [ - {file = "mkdocstrings-0.21.2-py3-none-any.whl", hash = "sha256:949ef8da92df9d692ca07be50616459a6b536083a25520fd54b00e8814ce019b"}, - {file = "mkdocstrings-0.21.2.tar.gz", hash = "sha256:304e56a2e90595708a38a13a278e538a67ad82052dd5c8b71f77a604a4f3d911"}, -] -mkdocstrings-python = [ - {file = "mkdocstrings_python-1.0.0-py3-none-any.whl", hash = "sha256:c59d67009a7a85172f4da990d8523e95606b6a1ff93a22a2351ad3b5f8cafed1"}, - {file = "mkdocstrings_python-1.0.0.tar.gz", hash = "sha256:b89d849df990204f909d5452548b6936a185f912da06208a93909bebe25d6e67"}, -] -mknotebooks = [ - {file = "mknotebooks-0.7.1-py3-none-any.whl", hash = "sha256:e2fa000b706683fc56b93adada7190a0da22ad85c4f1bfd5c4468cc3552b78e5"}, -] -mktestdocs = [ - {file = "mktestdocs-0.2.1-py2.py3-none-any.whl", hash = "sha256:55ad757e83227d5ba217eb285b8e44dc490601c4bbef52bc3331fea4510b72ec"}, - {file = "mktestdocs-0.2.1.tar.gz", hash = "sha256:44142b98223f02c7ba4629790d9ee83031fd4d8855577c6fbfc23103421d3872"}, -] -ml-dtypes = [ - {file = "ml_dtypes-0.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:377f2d5cfbf809b59188e0bfda4a0774e658541f575b637fee4850d99c2f9fdc"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87aa1cf83d41fed5a40fc27ee57ac4c1bf904e940f082531d3d58f1c318b5928"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee8ea629b8e3e20c6649852c1b9deacfa13384ab9337f2c9e717e401d102f23"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad765159ac6c18d5ee7d325fcf34d3106a9d9d7a49713d998f5cfa330a1459b4"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b9c5578dffd85637a7dd437192de18bc1a14eb6ba7d53ef40de3f84c51c789e5"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e8518c8fd2c38729f020125f39ef07b045f5c16d0846320c7252d7773285ee"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99fab8262d175c49bf1655c229244f301274e8289449c350ba4d5b95ade07d9a"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8de9bbf5bed587a1166699447ea14d1e8fe66d4e812811e37bf2f4d988475476"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a29fbf128583673eca0f43def1dbe77e02c1e8b8a8331db2877bbb57d091ef11"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273c306db846005b83a98c9c7ec3dc8fa20e8f11c3772c8e8c20cc12d8abfd4b"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41b6beeaea47e2466b94068664c9a45b2a65dd023aa4e5deeb5a73303661344e"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2de6c81b0da398d54aabdd7de599f2dfc43e30b65d9fad379a69f4cc4ae165d3"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:77970beeb3cf6ac559c4b6b393f24778a5abd34fafbaad82d5a0d17d0f148936"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffb7882dd46399217dc54f37affc899e0a29a4cfb63e5bf733ac0baf4a179c77"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5c9fe086756fbc1bf51296431d64429536093cf6e2ba592e042d7fc07c8514"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9218175b06764b8ddc95cb18d11a6c4b48a4b103a31c9ea2b2c3cd0cfc369f8"}, - {file = "ml_dtypes-0.1.0.tar.gz", hash = "sha256:c1fc0afe63ce99069f9d7e0693a61cfd0aea90241fc3821af9953d0c11f4048a"}, -] -msgpack = [ +name = "msgpack" +version = "1.0.5" +description = "MessagePack serializer" +optional = false +python-versions = "*" +files = [ {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, @@ -4147,7 +2637,14 @@ msgpack = [ {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, ] -multidict = [ + +[[package]] +name = "multidict" +version = "6.0.4" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, @@ -4223,47 +2720,201 @@ multidict = [ {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] -munch = [ + +[[package]] +name = "munch" +version = "2.5.0" +description = "A dot-accessible dictionary (a la JavaScript objects)" +optional = false +python-versions = "*" +files = [ {file = "munch-2.5.0-py2.py3-none-any.whl", hash = "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd"}, {file = "munch-2.5.0.tar.gz", hash = "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2"}, ] -mypy-extensions = [ + +[package.dependencies] +six = "*" + +[package.extras] +testing = ["astroid (>=1.5.3,<1.6.0)", "astroid (>=2.0)", "coverage", "pylint (>=1.7.2,<1.8.0)", "pylint (>=2.3.1,<2.4.0)", "pytest"] +yaml = ["PyYAML (>=5.1.0)"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -nbclient = [ + +[[package]] +name = "nbclient" +version = "0.7.4" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.7.0" +files = [ {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, ] -nbconvert = [ + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.3" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.4.0" +description = "Converting Jupyter Notebooks" +optional = false +python-versions = ">=3.7" +files = [ {file = "nbconvert-7.4.0-py3-none-any.whl", hash = "sha256:af5064a9db524f9f12f4e8be7f0799524bd5b14c1adea37e34e83c95127cc818"}, {file = "nbconvert-7.4.0.tar.gz", hash = "sha256:51b6c77b507b177b73f6729dba15676e42c4e92bcb00edc8cc982ee72e7d89d7"}, ] -nbformat = [ + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "*" +defusedxml = "*" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<3" +nbclient = ">=0.5.0" +nbformat = ">=5.1" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.0" + +[package.extras] +all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["nbconvert[qtpng]"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +webpdf = ["pyppeteer (>=1,<1.1)"] + +[[package]] +name = "nbformat" +version = "5.8.0" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.7" +files = [ {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, {file = "nbformat-5.8.0.tar.gz", hash = "sha256:46dac64c781f1c34dfd8acba16547024110348f9fc7eab0f31981c2a3dc48d1f"}, ] -nbstripout = [ + +[package.dependencies] +fastjsonschema = "*" +jsonschema = ">=2.6" +jupyter-core = "*" +traitlets = ">=5.1" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nbstripout" +version = "0.6.1" +description = "Strips outputs from Jupyter and IPython notebooks" +optional = false +python-versions = ">=3.6" +files = [ {file = "nbstripout-0.6.1-py2.py3-none-any.whl", hash = "sha256:5ff6eb0debbcd656c4a64db8e082a24fabcfc753a9e8c9f6d786971e8f29e110"}, {file = "nbstripout-0.6.1.tar.gz", hash = "sha256:9065bcdd1488b386e4f3c081ffc1d48f4513a2f8d8bf4d0d9a28208c5dafe9d3"}, ] -nest-asyncio = [ + +[package.dependencies] +nbformat = "*" + +[[package]] +name = "nest-asyncio" +version = "1.5.6" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"}, ] -networkx = [ + +[[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"}, ] -nodeenv = [ + +[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 = "nodeenv" +version = "1.7.0" +description = "Node.js virtual environment builder" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, ] -nox = [ + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "nox" +version = "2022.11.21" +description = "Flexible test automation." +optional = false +python-versions = ">=3.7" +files = [ {file = "nox-2022.11.21-py3-none-any.whl", hash = "sha256:0e41a990e290e274cb205a976c4c97ee3c5234441a8132c8c3fd9ea3c22149eb"}, {file = "nox-2022.11.21.tar.gz", hash = "sha256:e21c31de0711d1274ca585a2c5fde36b1aa962005ba8e9322bf5eeed16dcd684"}, ] -numpy = [ + +[package.dependencies] +argcomplete = ">=1.9.4,<3.0" +colorlog = ">=2.6.1,<7.0.0" +packaging = ">=20.9" +virtualenv = ">=14" + +[package.extras] +tox-to-nox = ["jinja2", "tox"] + +[[package]] +name = "numpy" +version = "1.24.3" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +files = [ {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, @@ -4293,23 +2944,89 @@ numpy = [ {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, ] -opt-einsum = [ + +[[package]] +name = "opt-einsum" +version = "3.3.0" +description = "Optimizing numpys einsum function" +optional = false +python-versions = ">=3.5" +files = [ {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, ] -optax = [ + +[package.dependencies] +numpy = ">=1.7" + +[package.extras] +docs = ["numpydoc", "sphinx (==1.2.3)", "sphinx-rtd-theme", "sphinxcontrib-napoleon"] +tests = ["pytest", "pytest-cov", "pytest-pep8"] + +[[package]] +name = "optax" +version = "0.1.5" +description = "A gradient processing and optimisation library in JAX." +optional = false +python-versions = ">=3.8" +files = [ {file = "optax-0.1.5-py3-none-any.whl", hash = "sha256:4057461448abd1fccdefd5e6c7ebc6ea8daa3105041f2631d6efd506544ecde0"}, {file = "optax-0.1.5.tar.gz", hash = "sha256:0aa379b56f51dbd525562f5ee6805a180a2616f3e9fe8080582352bcbb520f2e"}, ] -orbax-checkpoint = [ - {file = "orbax-checkpoint-0.2.2.tar.gz", hash = "sha256:9f6a260e3e2efe85c1e975599cfc8da0c691161f43fb67c54557d36265c95127"}, - {file = "orbax_checkpoint-0.2.2-py3-none-any.whl", hash = "sha256:8e1a385e28d2817a477dcdab601081bebb127b2c0fa3747a5e1a53f29f103bfa"}, + +[package.dependencies] +absl-py = ">=0.7.1" +chex = ">=0.1.5" +jax = ">=0.1.55" +jaxlib = ">=0.1.37" +numpy = ">=1.18.0" + +[[package]] +name = "orbax-checkpoint" +version = "0.2.3" +description = "Orbax Checkpoint" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orbax-checkpoint-0.2.3.tar.gz", hash = "sha256:155e0a2dceef2901122e66585171e1dff4f4a4d9d2abe43a2b514279b9a3dabd"}, + {file = "orbax_checkpoint-0.2.3-py3-none-any.whl", hash = "sha256:a001bf48f1cebc635b07263fa546473ea48be3e278c50d5ade880b9aafb96f8a"}, ] -packaging = [ + +[package.dependencies] +absl-py = "*" +cached_property = "*" +etils = "*" +importlib_resources = "*" +jax = ">=0.4.9" +jaxlib = "*" +msgpack = "*" +nest_asyncio = "*" +numpy = "*" +pyyaml = "*" +tensorstore = ">=0.1.35" +typing_extensions = "*" + +[package.extras] +dev = ["flax", "pytest", "pytest-xdist"] + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] -pandas = [ + +[[package]] +name = "pandas" +version = "1.5.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.8" +files = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, @@ -4338,31 +3055,102 @@ pandas = [ {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, ] -pandocfilters = [ + +[package.dependencies] +numpy = [ + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + +[[package]] +name = "pandocfilters" +version = "1.5.0" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, ] -parso = [ + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] -pathlib2 = [ + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pathlib2" +version = "2.3.7.post1" +description = "Object-oriented filesystem paths" +optional = false +python-versions = "*" +files = [ {file = "pathlib2-2.3.7.post1-py2.py3-none-any.whl", hash = "sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b"}, {file = "pathlib2-2.3.7.post1.tar.gz", hash = "sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641"}, ] -pathspec = [ + +[package.dependencies] +six = "*" + +[[package]] +name = "pathspec" +version = "0.11.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, ] -pexpect = [ + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, ] -pickleshare = [ + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +files = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] -pillow = [ + +[[package]] +name = "pillow" +version = "9.5.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.7" +files = [ {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, @@ -4430,35 +3218,132 @@ pillow = [ {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, ] -pkgutil-resolve-name = [ + +[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 = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, ] -planetary-computer = [ + +[[package]] +name = "planetary-computer" +version = "0.5.1" +description = "Planetary Computer SDK for Python" +optional = false +python-versions = ">=3.7" +files = [ {file = "planetary-computer-0.5.1.tar.gz", hash = "sha256:a46de4a6bab359a5b691f2059f5dbe842c92b45390b5f1ab465bdf2819008d35"}, {file = "planetary_computer-0.5.1-py3-none-any.whl", hash = "sha256:87cd7b89a8df33b71aab3a05b390ecedd3830ece1bb3ad33725019db30c9683f"}, ] -platformdirs = [ + +[package.dependencies] +click = ">=7.1" +pydantic = {version = ">=1.7.3", extras = ["dotenv"]} +pystac = ">=1.0.0" +pystac-client = ">=0.2.0" +pytz = ">=2020.5" +requests = ">=2.25.1" + +[package.extras] +adlfs = ["adlfs"] +azure = ["azure-storage-blob"] +dev = ["black", "flake8", "mypy", "pytest", "responses", "setuptools", "types-requests"] + +[[package]] +name = "platformdirs" +version = "3.5.1" +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.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] -pluggy = [ + +[package.extras] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.6" +files = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] -plum-dispatch = [ + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "plum-dispatch" +version = "2.1.0" +description = "Multiple dispatch in Python" +optional = false +python-versions = ">=3.7" +files = [ {file = "plum_dispatch-2.1.0-py3-none-any.whl", hash = "sha256:a1f2880b54507b84254a0423fefce4001b50f16c9f870bfea3892cb279061508"}, {file = "plum_dispatch-2.1.0.tar.gz", hash = "sha256:7c13a29f23b2a225f04780f7d054562c95c6e1db251f9e5fc5325dbaecaa2567"}, ] -pre-commit = [ + +[package.dependencies] +beartype = "*" + +[package.extras] +dev = ["black (==22.10.0)", "build", "coveralls", "ghp-import", "ipython", "jupyter-book", "numpy", "pre-commit", "pytest (>=6)", "pytest-cov", "tox", "wheel"] + +[[package]] +name = "pre-commit" +version = "3.3.1" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.8" +files = [ {file = "pre_commit-3.3.1-py2.py3-none-any.whl", hash = "sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9"}, {file = "pre_commit-3.3.1.tar.gz", hash = "sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907"}, ] -prompt-toolkit = [ + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + +[[package]] +name = "prompt-toolkit" +version = "3.0.38" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, ] -psutil = [ + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "5.9.5" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, @@ -4474,27 +3359,83 @@ psutil = [ {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, ] -ptyprocess = [ + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] -pure-eval = [ + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] -py = [ + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pybtex = [ + +[[package]] +name = "pybtex" +version = "0.24.0" +description = "A BibTeX-compatible bibliography processor in Python" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, ] -pycparser = [ + +[package.dependencies] +latexcodec = ">=1.0.4" +PyYAML = ">=3.01" +six = "*" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] -pydantic = [ + +[[package]] +name = "pydantic" +version = "1.10.7" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, @@ -4532,31 +3473,122 @@ pydantic = [ {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, ] -pydocstyle = [ + +[package.dependencies] +python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pydocstyle" +version = "6.3.0" +description = "Python docstring style checker" +optional = false +python-versions = ">=3.6" +files = [ {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, ] -pygments = [ + +[package.dependencies] +snowballstemmer = ">=2.2.0" + +[package.extras] +toml = ["tomli (>=1.2.3)"] + +[[package]] +name = "pygments" +version = "2.15.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, ] -pylint = [ + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pylint" +version = "2.17.4" +description = "python code static checker" +optional = false +python-versions = ">=3.7.2" +files = [ {file = "pylint-2.17.4-py3-none-any.whl", hash = "sha256:7a1145fb08c251bdb5cca11739722ce64a63db479283d10ce718b2460e54123c"}, {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, ] -pymdown-extensions = [ + +[package.dependencies] +astroid = ">=2.15.4,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pymdown-extensions" +version = "9.11" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.7" +files = [ {file = "pymdown_extensions-9.11-py3-none-any.whl", hash = "sha256:a499191d8d869f30339de86fcf072a787e86c42b6f16f280f5c2cf174182b7f3"}, {file = "pymdown_extensions-9.11.tar.gz", hash = "sha256:f7e86c1d3981f23d9dc43294488ecb54abadd05b0be4bf8f0e15efc90f7853ff"}, ] -pypandoc = [ + +[package.dependencies] +markdown = ">=3.2" +pyyaml = "*" + +[[package]] +name = "pypandoc" +version = "1.11" +description = "Thin wrapper for pandoc." +optional = false +python-versions = ">=3.6" +files = [ {file = "pypandoc-1.11-py3-none-any.whl", hash = "sha256:b260596934e9cfc6513056110a7c8600171d414f90558bf4407e68b209be8007"}, {file = "pypandoc-1.11.tar.gz", hash = "sha256:7f6d68db0e57e0f6961bec2190897118c4d305fc2d31c22cd16037f22ee084a5"}, ] -pyparsing = [ + +[[package]] +name = "pyparsing" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] -pyproj = [ + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyproj" +version = "3.5.0" +description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" +optional = false +python-versions = ">=3.8" +files = [ {file = "pyproj-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6475ce653880938468a1a1b7321267243909e34b972ba9e53d5982c41d555918"}, {file = "pyproj-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61e4ad57d89b03a7b173793b31bca8ee110112cde1937ef0f42a70b9120c827d"}, {file = "pyproj-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdd2021bb6f7f346bfe1d2a358aa109da017d22c4704af2d994e7c7ee0a7a53"}, @@ -4593,7 +3625,17 @@ pyproj = [ {file = "pyproj-3.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a87b419a2a352413fbf759ecb66da9da50bd19861c8f26db6a25439125b27b9"}, {file = "pyproj-3.5.0.tar.gz", hash = "sha256:9859d1591c1863414d875ae0759e72c2cffc01ab989dc64137fbac572cc81bf6"}, ] -pyrsistent = [ + +[package.dependencies] +certifi = "*" + +[[package]] +name = "pyrsistent" +version = "0.19.3" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.7" +files = [ {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, @@ -4622,47 +3664,183 @@ pyrsistent = [ {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, ] -pystac = [ + +[[package]] +name = "pystac" +version = "1.7.3" +description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." +optional = false +python-versions = ">=3.8" +files = [ {file = "pystac-1.7.3-py3-none-any.whl", hash = "sha256:2b1b5e11b995e443376ca1d195609d95723f690c8d192604bc00091fcdf52e4c"}, {file = "pystac-1.7.3.tar.gz", hash = "sha256:6848074fad6665ac631abd62c692bb868de37379615db90f4d913dca37f844ce"}, ] -pystac-client = [ + +[package.dependencies] +python-dateutil = ">=2.7.0" + +[package.extras] +orjson = ["orjson (>=3.5)"] +urllib3 = ["urllib3 (>=1.26)"] +validation = ["jsonschema (>=4.0.1)"] + +[[package]] +name = "pystac-client" +version = "0.6.1" +description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." +optional = false +python-versions = ">=3.8" +files = [ {file = "pystac-client-0.6.1.tar.gz", hash = "sha256:1981537ad0fd167b08790eb3f41e7c2788438f461125b42b47bc934eaf1adcb1"}, {file = "pystac_client-0.6.1-py3-none-any.whl", hash = "sha256:124d81bd9653b3e12c7ff244bf0dad420cadeaf86ab394dfdc804958ff723fcd"}, ] -pytest = [ + +[package.dependencies] +pystac = ">=1.7.0" +python-dateutil = ">=2.7.0" +requests = ">=2.27.1" + +[package.extras] +validation = ["jsonschema (>=4.5.1)"] + +[[package]] +name = "pytest" +version = "7.3.1" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, ] -pytest-cov = [ + +[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", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.6" +files = [ {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, ] -pytest-pretty = [ + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-pretty" +version = "1.2.0" +description = "pytest plugin for printing summary data as I want it" +optional = false +python-versions = ">=3.7" +files = [ {file = "pytest_pretty-1.2.0-py3-none-any.whl", hash = "sha256:6f79122bf53864ae2951b6c9e94d7a06a87ef753476acd4588aeac018f062036"}, {file = "pytest_pretty-1.2.0.tar.gz", hash = "sha256:105a355f128e392860ad2c478ae173ff96d2f03044692f9818ff3d49205d3a60"}, ] -pytest-xdist = [ + +[package.dependencies] +pytest = ">=7" +rich = ">=12" + +[[package]] +name = "pytest-xdist" +version = "3.2.1" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +optional = false +python-versions = ">=3.7" +files = [ {file = "pytest-xdist-3.2.1.tar.gz", hash = "sha256:1849bd98d8b242b948e472db7478e090bf3361912a8fed87992ed94085f54727"}, {file = "pytest_xdist-3.2.1-py3-none-any.whl", hash = "sha256:37290d161638a20b672401deef1cba812d110ac27e35d213f091d15b8beb40c9"}, ] -python-dateutil = [ + +[package.dependencies] +execnet = ">=1.1" +pytest = ">=6.2.0" + +[package.extras] +psutil = ["psutil (>=3.0)"] +setproctitle = ["setproctitle"] +testing = ["filelock"] + +[[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"}, ] -python-dotenv = [ + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, ] -pytkdocs = [ + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "pytkdocs" +version = "0.16.1" +description = "Load Python objects documentation." +optional = false +python-versions = ">=3.7" +files = [ {file = "pytkdocs-0.16.1-py3-none-any.whl", hash = "sha256:a8c3f46ecef0b92864cc598e9101e9c4cf832ebbf228f50c84aa5dd850aac379"}, {file = "pytkdocs-0.16.1.tar.gz", hash = "sha256:e2ccf6dfe9dbbceb09818673f040f1a7c32ed0bffb2d709b06be6453c4026045"}, ] -pytz = [ + +[package.dependencies] +astunparse = {version = ">=1.6", markers = "python_version < \"3.9\""} + +[package.extras] +numpy-style = ["docstring_parser (>=0.7)"] + +[[package]] +name = "pytz" +version = "2023.3" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] -pywin32 = [ + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, @@ -4678,7 +3856,14 @@ pywin32 = [ {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] -pyyaml = [ + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, @@ -4720,11 +3905,28 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] -pyyaml-env-tag = [ + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] -pyzmq = [ + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "pyzmq" +version = "25.0.2" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.6" +files = [ {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ac178e666c097c8d3deb5097b58cd1316092fc43e8ef5b5fdb259b51da7e7315"}, {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:659e62e1cbb063151c52f5b01a38e1df6b54feccfa3e2509d44c35ca6d7962ee"}, {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8280ada89010735a12b968ec3ea9a468ac2e04fddcc1cede59cb7f5178783b9c"}, @@ -4803,7 +4005,17 @@ pyzmq = [ {file = "pyzmq-25.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:56a94ab1d12af982b55ca96c6853db6ac85505e820d9458ac76364c1998972f4"}, {file = "pyzmq-25.0.2.tar.gz", hash = "sha256:6b8c1bbb70e868dc88801aa532cae6bd4e3b5233784692b786f17ad2962e5149"}, ] -rasterio = [ + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "rasterio" +version = "1.3.6" +description = "Fast and direct raster I/O for use with Numpy and SciPy" +optional = false +python-versions = ">=3.8" +files = [ {file = "rasterio-1.3.6-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:23a8d10ba17301029962a5667915381a8b4711ed80b712eb71cf68834cb5f946"}, {file = "rasterio-1.3.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76b6bd4b566cd733f0ddd05ba88bea3f96705ff74e2e5fab73ead2a26cbc5979"}, {file = "rasterio-1.3.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50785004d7adf66cf96c9c3498cf530ec91292e9349e66e8d1f1183085ee93b1"}, @@ -4822,7 +4034,33 @@ rasterio = [ {file = "rasterio-1.3.6-cp39-cp39-win_amd64.whl", hash = "sha256:cb3288add5d55248f5d48815f9d509819ba8985cd0302d2e8dd743f83c5ec96d"}, {file = "rasterio-1.3.6.tar.gz", hash = "sha256:c8b90eb10e16102d1ab0334a7436185f295de1c07f0d197e206d1c005fc33905"}, ] -regex = [ + +[package.dependencies] +affine = "*" +attrs = "*" +certifi = "*" +click = ">=4.0" +click-plugins = "*" +cligj = ">=0.5" +numpy = ">=1.18" +setuptools = "*" +snuggs = ">=1.4.1" + +[package.extras] +all = ["boto3 (>=1.2.4)", "ghp-import", "hypothesis", "ipython (>=2.0)", "matplotlib", "numpydoc", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely", "sphinx", "sphinx-rtd-theme"] +docs = ["ghp-import", "numpydoc", "sphinx", "sphinx-rtd-theme"] +ipython = ["ipython (>=2.0)"] +plot = ["matplotlib"] +s3 = ["boto3 (>=1.2.4)"] +test = ["boto3 (>=1.2.4)", "hypothesis", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely"] + +[[package]] +name = "regex" +version = "2023.5.5" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.6" +files = [ {file = "regex-2023.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:48c9ec56579d4ba1c88f42302194b8ae2350265cb60c64b7b9a88dcb7fbde309"}, {file = "regex-2023.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f4541550459c08fdd6f97aa4e24c6f1932eec780d58a2faa2068253df7d6ff"}, {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e22e4460f0245b468ee645156a4f84d0fc35a12d9ba79bd7d79bdcd2f9629d"}, @@ -4912,19 +4150,79 @@ regex = [ {file = "regex-2023.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:1307aa4daa1cbb23823d8238e1f61292fd07e4e5d8d38a6efff00b67a7cdb764"}, {file = "regex-2023.5.5.tar.gz", hash = "sha256:7d76a8a1fc9da08296462a18f16620ba73bcbf5909e42383b253ef34d9d5141e"}, ] -requests = [ + +[[package]] +name = "requests" +version = "2.30.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, ] -rich = [ + +[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 = "rich" +version = "13.3.5" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, ] -rioxarray = [ + +[package.dependencies] +markdown-it-py = ">=2.2.0,<3.0.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "rioxarray" +version = "0.13.4" +description = "geospatial xarray extension powered by rasterio" +optional = false +python-versions = ">=3.8" +files = [ {file = "rioxarray-0.13.4-py3-none-any.whl", hash = "sha256:56eef711d9817d3c729c1a267c940e7dff66bfc874a0b24ed3604ea2f958dfb2"}, {file = "rioxarray-0.13.4.tar.gz", hash = "sha256:0cad24ad2c3c5ee181a0cfad2b8c2152a609b7eb118a3430034aec171e9cf14f"}, ] -ruff = [ + +[package.dependencies] +numpy = ">=1.21" +packaging = "*" +pyproj = ">=2.2" +rasterio = ">=1.1.1" +xarray = ">=0.17" + +[package.extras] +all = ["dask", "mypy", "nbsphinx", "netcdf4", "pre-commit", "pylint", "pytest (>=3.6)", "pytest-cov", "pytest-timeout", "scipy", "sphinx-click", "sphinx-rtd-theme"] +dev = ["dask", "mypy", "nbsphinx", "netcdf4", "pre-commit", "pylint", "pytest (>=3.6)", "pytest-cov", "pytest-timeout", "scipy", "sphinx-click", "sphinx-rtd-theme"] +doc = ["nbsphinx", "sphinx-click", "sphinx-rtd-theme"] +interp = ["scipy"] +test = ["dask", "netcdf4", "pytest (>=3.6)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ruff" +version = "0.0.259" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ {file = "ruff-0.0.259-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f3938dc45e2a3f818e9cbd53007265c22246fbfded8837b2c563bf0ebde1a226"}, {file = "ruff-0.0.259-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:22e1e35bf5f12072cd644d22afd9203641ccf258bc14ff91aa1c43dc14f6047d"}, {file = "ruff-0.0.259-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2fb20e89e85d147c85caa807707a1488bccc1f3854dc3d53533e89b52a0c5ff"}, @@ -4943,7 +4241,14 @@ ruff = [ {file = "ruff-0.0.259-py3-none-win_arm64.whl", hash = "sha256:e4f39e18702de69faaaee3969934b92d7467285627f99a5b6ecd55a7d9f5d086"}, {file = "ruff-0.0.259.tar.gz", hash = "sha256:8b56496063ab3bfdf72339a5fbebb8bd46e5c5fee25ef11a9f03b208fa0562ec"}, ] -scikit-learn = [ + +[[package]] +name = "scikit-learn" +version = "1.2.2" +description = "A set of python modules for machine learning and data mining" +optional = false +python-versions = ">=3.8" +files = [ {file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7"}, {file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f"}, {file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb"}, @@ -4966,7 +4271,26 @@ scikit-learn = [ {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89"}, {file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3"}, ] -scipy = [ + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scipy" +version = "1.10.1" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = "<3.12,>=3.8" +files = [ {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, @@ -4989,19 +4313,59 @@ scipy = [ {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, ] -seaborn = [ + +[package.dependencies] +numpy = ">=1.19.5,<1.27.0" + +[package.extras] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "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 = "seaborn" +version = "0.12.2" +description = "Statistical data visualization" +optional = false +python-versions = ">=3.7" +files = [ {file = "seaborn-0.12.2-py3-none-any.whl", hash = "sha256:ebf15355a4dba46037dfd65b7350f014ceb1f13c05e814eda2c9f5fd731afc08"}, {file = "seaborn-0.12.2.tar.gz", hash = "sha256:374645f36509d0dcab895cba5b47daf0586f77bfe3b36c97c607db7da5be0139"}, ] -setuptools = [ + +[package.dependencies] +matplotlib = ">=3.1,<3.6.1 || >3.6.1" +numpy = ">=1.17,<1.24.0 || >1.24.0" +pandas = ">=0.25" + +[package.extras] +dev = ["flake8", "flit", "mypy", "pandas-stubs", "pre-commit", "pytest", "pytest-cov", "pytest-xdist"] +docs = ["ipykernel", "nbconvert", "numpydoc", "pydata_sphinx_theme (==0.10.0rc2)", "pyyaml", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] +stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] + +[[package]] +name = "setuptools" +version = "67.7.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.7" +files = [ {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, ] -setuptools-scm = [ - {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, - {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, -] -shapely = [ + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "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 (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "shapely" +version = "2.0.1" +description = "Manipulation and analysis of geometric objects" +optional = false +python-versions = ">=3.7" +files = [ {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b06d031bc64149e340448fea25eee01360a58936c89985cf584134171e05863f"}, {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a6ac34c16f4d5d3c174c76c9d7614ec8fe735f8f82b6cc97a46b54f386a86bf"}, {file = "shapely-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:865bc3d7cc0ea63189d11a0b1120d1307ed7a64720a8bfa5be2fde5fc6d0d33f"}, @@ -5041,42 +4405,154 @@ shapely = [ {file = "shapely-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bca57b683e3d94d0919e2f31e4d70fdfbb7059650ef1b431d9f4e045690edcd5"}, {file = "shapely-2.0.1.tar.gz", hash = "sha256:66a6b1a3e72ece97fc85536a281476f9b7794de2e646ca8a4517e2e3c1446893"}, ] -simple-pytree = [ + +[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 = "simple-pytree" +version = "0.1.7" +description = "" +optional = false +python-versions = ">=3.8,<3.12" +files = [ {file = "simple_pytree-0.1.7-py3-none-any.whl", hash = "sha256:d84834955b153eeb22a944bdfeff7ce1a261e31ef347f0b1e07bb0eedbb3f0ea"}, {file = "simple_pytree-0.1.7.tar.gz", hash = "sha256:037c5c492de191038c6625fb223da572ec321e829150f48c452e100d69bbffba"}, ] -six = [ + +[package.dependencies] +jax = "*" +jaxlib = "*" + +[[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"}, ] -smmap = [ + +[[package]] +name = "smmap" +version = "5.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +optional = false +python-versions = ">=3.6" +files = [ {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, ] -snowballstemmer = [ + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -snuggs = [ + +[[package]] +name = "snuggs" +version = "1.4.7" +description = "Snuggs are s-expressions for Numpy" +optional = false +python-versions = "*" +files = [ {file = "snuggs-1.4.7-py3-none-any.whl", hash = "sha256:988dde5d4db88e9d71c99457404773dabcc7a1c45971bfbe81900999942d9f07"}, {file = "snuggs-1.4.7.tar.gz", hash = "sha256:501cf113fe3892e14e2fee76da5cd0606b7e149c411c271898e6259ebde2617b"}, ] -soupsieve = [ + +[package.dependencies] +numpy = "*" +pyparsing = ">=2.1.6" + +[package.extras] +test = ["hypothesis", "pytest"] + +[[package]] +name = "soupsieve" +version = "2.4.1" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.7" +files = [ {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] -stack-data = [ + +[[package]] +name = "stack-data" +version = "0.6.2" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, ] -tabulate = [ + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, ] -tensorflow-probability = [ + +[package.extras] +widechars = ["wcwidth"] + +[[package]] +name = "tensorflow-probability" +version = "0.19.0" +description = "Probabilistic modeling and statistical inference in TensorFlow" +optional = false +python-versions = "*" +files = [ {file = "tensorflow_probability-0.19.0-py2.py3-none-any.whl", hash = "sha256:ee70967fbd52b09e9c5ec148a9437c4cf3f9e9d689cdca400a1bc921f21cdcac"}, ] -tensorstore = [ + +[package.dependencies] +absl-py = "*" +cloudpickle = ">=1.3" +decorator = "*" +dm-tree = "*" +gast = ">=0.3.2" +numpy = ">=1.13.3" +six = ">=1.10.0" + +[package.extras] +jax = ["jax", "jaxlib"] +tfds = ["tensorflow-datasets (>=2.2.0)"] + +[[package]] +name = "tensorstore" +version = "0.1.36" +description = "Read and write large, multi-dimensional arrays" +optional = false +python-versions = ">=3.8" +files = [ {file = "tensorstore-0.1.36-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:b1e3038778fd47ca351442276ff419bd3fb2e1e7c5c6c9956b341de81f869df1"}, {file = "tensorstore-0.1.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25cc8e2c865b7193d68524752d14a39bce39e6797eeda47ce02062dc97c9b865"}, {file = "tensorstore-0.1.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33ad5669e5f3ee705718978f5519d96b25ff43f607730ac473947b0bac4c66d9"}, @@ -5095,31 +4571,90 @@ tensorstore = [ {file = "tensorstore-0.1.36-cp39-cp39-win_amd64.whl", hash = "sha256:acc46ed5e59faee6823ad39b807daeb40447fac2068163b7c558cc3a0d7a0b71"}, {file = "tensorstore-0.1.36.tar.gz", hash = "sha256:733b629a65f1d47cc1b19fb1df2de75111ae228081655746d335ed3c21902bbd"}, ] -threadpoolctl = [ + +[package.dependencies] +numpy = ">=1.16.0" + +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +optional = false +python-versions = ">=3.6" +files = [ {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, ] -tinycss2 = [ + +[[package]] +name = "tinycss2" +version = "1.2.1" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.7" +files = [ {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, ] -toml = [ + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [ + +[[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"}, ] -tomlkit = [ + +[[package]] +name = "tomlkit" +version = "0.11.8" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, ] -toolz = [ + +[[package]] +name = "toolz" +version = "0.12.0" +description = "List processing tools and functional utilities" +optional = false +python-versions = ">=3.5" +files = [ {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, ] -tornado = [ + +[[package]] +name = "tornado" +version = "6.3.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:db181eb3df8738613ff0a26f49e1b394aade05034b01200a63e9662f347d4415"}, {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b4e7b956f9b5e6f9feb643ea04f07e7c6b49301e03e0023eedb01fa8cf52f579"}, {file = "tornado-6.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661aa8bc0e9d83d757cd95b6f6d1ece8ca9fd1ccdd34db2de381e25bf818233"}, @@ -5132,38 +4667,146 @@ tornado = [ {file = "tornado-6.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:1285f0691143f7ab97150831455d4db17a267b59649f7bd9700282cba3d5e771"}, {file = "tornado-6.3.1.tar.gz", hash = "sha256:5e2f49ad371595957c50e42dd7e5c14d64a6843a3cf27352b69c706d1b5918af"}, ] -tqdm = [ + +[[package]] +name = "tqdm" +version = "4.65.0" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, ] -traitlets = [ + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "traitlets" +version = "5.9.0" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.7" +files = [ {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] -typeguard = [ + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] + +[[package]] +name = "typeguard" +version = "3.0.2" +description = "Run-time type checker for Python" +optional = false +python-versions = ">=3.7.4" +files = [ {file = "typeguard-3.0.2-py3-none-any.whl", hash = "sha256:bbe993854385284ab42fd5bd3bee6f6556577ce8b50696d6cb956d704f286c8e"}, {file = "typeguard-3.0.2.tar.gz", hash = "sha256:fee5297fdb28f8e9efcb8142b5ee219e02375509cd77ea9d270b5af826358d5a"}, ] -typing-extensions = [ + +[package.dependencies] +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["mypy (>=0.991)", "pytest (>=7)"] + +[[package]] +name = "typing-extensions" +version = "4.5.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +optional = false +python-versions = ">=3.7" +files = [ {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] -uc-micro-py = [ + +[[package]] +name = "uc-micro-py" +version = "1.0.2" +description = "Micro subset of unicode data files for linkify-it-py projects." +optional = false +python-versions = ">=3.7" +files = [ {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, ] -urllib3 = [ + +[package.extras] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "urllib3" +version = "2.0.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, ] -validators = [ + +[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 = "validators" +version = "0.20.0" +description = "Python Data Validation for Humans™." +optional = false +python-versions = ">=3.4" +files = [ {file = "validators-0.20.0.tar.gz", hash = "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"}, ] -virtualenv = [ + +[package.dependencies] +decorator = ">=3.4.0" + +[package.extras] +test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] + +[[package]] +name = "virtualenv" +version = "20.23.0" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, ] -watchdog = [ + +[package.dependencies] +distlib = ">=0.3.6,<1" +filelock = ">=3.11,<4" +platformdirs = ">=3.2,<4" + +[package.extras] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] + +[[package]] +name = "watchdog" +version = "3.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.7" +files = [ {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, @@ -5192,27 +4835,78 @@ watchdog = [ {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, ] -watermark = [ + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "watermark" +version = "2.3.1" +description = "IPython magic function to print date/time stamps and various system information." +optional = false +python-versions = ">=3.7" +files = [ {file = "watermark-2.3.1-py2.py3-none-any.whl", hash = "sha256:8e2681e512660e50d2aa460fd7d40d8ed2862735ae5087fc0ec7752fb10ee29c"}, {file = "watermark-2.3.1.tar.gz", hash = "sha256:0a69eb017f4f96e909739f25ce1a3bd0729c65d8cf4294ea07d609322360019a"}, ] -wcwidth = [ + +[package.dependencies] +ipython = "*" + +[[package]] +name = "wcwidth" +version = "0.2.6" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] -webencodings = [ + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] -wheel = [ + +[[package]] +name = "wheel" +version = "0.40.0" +description = "A built-package format for Python" +optional = false +python-versions = ">=3.7" +files = [ {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"}, {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"}, ] -widgetsnbextension = [ + +[package.extras] +test = ["pytest (>=6.0.0)"] + +[[package]] +name = "widgetsnbextension" +version = "4.0.7" +description = "Jupyter interactive widgets for Jupyter Notebook" +optional = false +python-versions = ">=3.7" +files = [ {file = "widgetsnbextension-4.0.7-py3-none-any.whl", hash = "sha256:be3228a73bbab189a16be2d4a3cd89ecbd4e31948bfdc64edac17dcdee3cd99c"}, {file = "widgetsnbextension-4.0.7.tar.gz", hash = "sha256:ea67c17a7cd4ae358f8f46c3b304c40698bc0423732e3f273321ee141232c8be"}, ] -wrapt = [ + +[[package]] +name = "wrapt" +version = "1.15.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, @@ -5289,15 +4983,65 @@ wrapt = [ {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] -xarray = [ + +[[package]] +name = "xarray" +version = "2023.1.0" +description = "N-D labeled arrays and datasets in Python" +optional = false +python-versions = ">=3.8" +files = [ {file = "xarray-2023.1.0-py3-none-any.whl", hash = "sha256:7e530b1deafdd43e5c2b577d0944e6b528fbe88045fd849e49a8d11871ecd522"}, {file = "xarray-2023.1.0.tar.gz", hash = "sha256:7bee552751ff1b29dab8b7715726e5ecb56691ac54593cf4881dff41978ce0cd"}, ] -xdoctest = [ + +[package.dependencies] +numpy = ">=1.20" +packaging = ">=21.3" +pandas = ">=1.3" + +[package.extras] +accel = ["bottleneck", "flox", "numbagg", "scipy"] +complete = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "matplotlib", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scipy", "seaborn", "zarr"] +docs = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "ipykernel", "ipython", "jupyter-client", "matplotlib", "nbsphinx", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scanpydoc", "scipy", "seaborn", "sphinx-autosummary-accessors", "sphinx-rtd-theme", "zarr"] +io = ["cfgrib", "cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "rasterio", "scipy", "zarr"] +parallel = ["dask[complete]"] +viz = ["matplotlib", "nc-time-axis", "seaborn"] + +[[package]] +name = "xdoctest" +version = "1.1.1" +description = "A rewrite of the builtin doctest module" +optional = false +python-versions = ">=3.6" +files = [ {file = "xdoctest-1.1.1-py3-none-any.whl", hash = "sha256:d59d4ed91cb92e4430ef0ad1b134a2bef02adff7d2fb9c9f057547bee44081a2"}, {file = "xdoctest-1.1.1.tar.gz", hash = "sha256:2eac8131bdcdf2781b4e5a62d6de87f044b730cc8db8af142a51bb29c245e779"}, ] -yarl = [ + +[package.dependencies] +six = "*" + +[package.extras] +all = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "codecov", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "pytest", "pytest", "pytest", "pytest-cov", "six", "tomli", "typing"] +all-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "codecov (==2.0.15)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "six (==1.11.0)", "tomli (==0.2.0)", "typing (==3.7.4)"] +colors = ["Pygments", "Pygments", "colorama"] +jupyter = ["IPython", "IPython", "attrs", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert"] +optional = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "tomli"] +optional-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "tomli (==0.2.0)"] +runtime-strict = ["six (==1.11.0)"] +tests = ["codecov", "pytest", "pytest", "pytest", "pytest-cov", "typing"] +tests-binary = ["cmake", "cmake", "ninja", "ninja", "pybind11", "pybind11", "scikit-build", "scikit-build"] +tests-binary-strict = ["cmake (==3.21.2)", "cmake (==3.25.0)", "ninja (==1.10.2)", "ninja (==1.11.1)", "pybind11 (==2.10.3)", "pybind11 (==2.7.1)", "scikit-build (==0.11.1)", "scikit-build (==0.16.1)"] +tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "typing (==3.7.4)"] + +[[package]] +name = "yarl" +version = "1.9.2" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82"}, {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8"}, {file = "yarl-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9"}, @@ -5373,7 +5117,27 @@ yarl = [ {file = "yarl-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18"}, {file = "yarl-1.9.2.tar.gz", hash = "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571"}, ] -zipp = [ + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zipp" +version = "3.15.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.7" +files = [ {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, ] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.8,<3.12" +content-hash = "6e8522a727760f42f1c044d42954a92abff6188cee00ae5d3066d766a127fb06" diff --git a/pyproject.toml b/pyproject.toml index a20ecb254..940f4fe0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,16 +16,16 @@ packages = [{include = "gpjax"}] [tool.poetry.dependencies] python = ">=3.8,<3.12" -jax = ">=0.4.1" optax = "^0.1.4" jaxtyping = "^0.2.15" tqdm = "^4.65.0" simple-pytree = "^0.1.7" tensorflow-probability = "^0.19.0" -orbax-checkpoint = "^0.2.0" beartype = "^0.13.1" -jaxlib = "0.4.7" # Temporary fix: https://github.com/google/jax/issues/15951 plum-dispatch = "^2.1.0" +jax = ">=0.4.10" +jaxlib = ">=0.4.10" +orbax-checkpoint = ">=0.2.3" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" From 5f0f49db39d0f0502d18cea5a2ff7688c0924595 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 06:25:48 +0200 Subject: [PATCH 35/76] Add ELBO benchmark --- benchmarks/stochastic.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 benchmarks/stochastic.py diff --git a/benchmarks/stochastic.py b/benchmarks/stochastic.py new file mode 100644 index 000000000..14681535f --- /dev/null +++ b/benchmarks/stochastic.py @@ -0,0 +1,39 @@ +from jax import config + +config.update("jax_enable_x64", True) +import jax +import jax.numpy as jnp +import jax.random as jr + +import gpjax as gpx +from gpjax.fit import get_batch + + +class Sparse: + param_names = ["n_data", "n_inducing", "batch_size"] + params = [[10000, 20000, 50000], [10, 20, 50, 100, 200], [32, 64, 128, 256]] + + def setup(self, n_datapoints: int, n_inducing: int, batch_size: int): + key = jr.PRNGKey(123) + self.X = jr.normal(key=key, shape=(n_datapoints, 1)) + self.y = jnp.sin(self.X[:, :1]) + self.data = gpx.Dataset(X=self.X, y=self.y) + kernel = gpx.kernels.RBF(active_dims=list(range(1))) + meanf = gpx.mean_functions.Constant() + self.prior = gpx.Prior(kernel=kernel, mean_function=meanf) + self.likelihood = gpx.likelihoods.Gaussian(num_datapoints=self.data.n) + self.posterior = self.prior * self.likelihood + + Z = jnp.linspace(self.X.min(), self.X.max(), n_inducing).reshape(-1, 1) + self.q = gpx.VariationalGaussian(posterior=self.posterior, inducing_inputs=Z) + self.objective = gpx.ELBO(negative=True) + + def time_eval(self, n_datapoints: int, n_dims: int, batch_size: int): + key = jr.PRNGKey(123) + batch = get_batch(train_data=self.data, batch_size=batch_size, key=key) + self.objective(self.q, batch) + + def time_grad(self, n_datapoints: int, n_dims: int, batch_size: int): + key = jr.PRNGKey(123) + batch = get_batch(train_data=self.data, batch_size=batch_size, key=key) + jax.grad(self.objective)(self.q, batch) From 373116cf90cc7735328f05350349af2372309258 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 12:06:00 +0200 Subject: [PATCH 36/76] Add typing --- benchmarks/kernels.py | 38 +++++++++++++++++++------------------- benchmarks/linops.py | 10 +++++----- benchmarks/objectives.py | 18 +++++++++--------- benchmarks/predictions.py | 12 ++++++------ benchmarks/sparse.py | 6 +++--- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/benchmarks/kernels.py b/benchmarks/kernels.py index a1074581d..d9d202931 100644 --- a/benchmarks/kernels.py +++ b/benchmarks/kernels.py @@ -11,7 +11,7 @@ class Kernels: param_names = ["n_data", "dimensionality"] params = [[10, 100, 500, 1000, 2000], [1, 2, 5]] - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.uniform( key=key, minval=-3.0, maxval=3.0, shape=(n_datapoints, n_dims) @@ -19,81 +19,81 @@ def setup(self, n_datapoints, n_dims): class RBF(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.RBF(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class Matern12(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.Matern12(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class Matern32(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.Matern32(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class Matern52(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.Matern52(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class PoweredExponential(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.PoweredExponential(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class RationalQuadratic(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.RationalQuadratic(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class Polynomial(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.Polynomial(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class Linear(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.Linear(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) class ArcCosine(Kernels): - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): super().setup(n_datapoints, n_dims) self.kernel = kernels.ArcCosine(active_dims=list(range(n_dims))) - def time_covfunc_call(self, n_datapoints, n_dims): + def time_covfunc_call(self, n_datapoints: int, n_dims: int): self.kernel.gram(self.X) diff --git a/benchmarks/linops.py b/benchmarks/linops.py index 3772ec289..a9fd6bd01 100644 --- a/benchmarks/linops.py +++ b/benchmarks/linops.py @@ -13,20 +13,20 @@ class LinOps: param_names = ["n_data"] params = [[10, 100, 200, 500, 1000]] - def setup(self, n_datapoints): + def setup(self, n_datapoints: int): key = jr.PRNGKey(123) self.X = jnp.asarray(make_spd_matrix(n_dim=n_datapoints, random_state=123)) self.y = jr.normal(key=key, shape=(n_datapoints, 1)) self.linop = DenseLinearOperator(matrix=self.X) - def time_root(self, n_datapoints): + def time_root(self, n_datapoints: int): self.linop.to_root() - def time_inverse(self, n_datapoints): + def time_inverse(self, n_datapoints: int): self.linop.inverse() - def time_logdet(self, n_datapoints): + def time_logdet(self, n_datapoints: int): self.linop.log_det() - def time_solve(self, n_datapoints): + def time_solve(self, n_datapoints: int): self.linop.solve(self.y) diff --git a/benchmarks/objectives.py b/benchmarks/objectives.py index 077269191..dd217b42b 100644 --- a/benchmarks/objectives.py +++ b/benchmarks/objectives.py @@ -15,7 +15,7 @@ class Gaussian: ] params = [[10, 100, 200, 500, 1000], [1, 2, 5]] - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) self.y = jnp.sin(self.X[:, :1]) @@ -27,10 +27,10 @@ def setup(self, n_datapoints, n_dims): self.objective = gpx.ConjugateMLL() self.posterior = self.prior * self.likelihood - def time_eval(self, n_datapoints, n_dims): + def time_eval(self, n_datapoints: int, n_dims: int): self.objective.step(self.posterior, self.data).block_until_ready() - def time_grad(self, n_datapoints, n_dims): + def time_grad(self, n_datapoints: int, n_dims: int): jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) @@ -41,7 +41,7 @@ class Bernoulli: ] params = [[10, 100, 200, 500, 1000], [1, 2, 5]] - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) self.y = jnp.where(jnp.sin(self.X[:, :1]) > 0, 1, 0) @@ -53,10 +53,10 @@ def setup(self, n_datapoints, n_dims): self.objective = gpx.LogPosteriorDensity() self.posterior = self.prior * self.likelihood - def time_eval(self, n_datapoints, n_dims): + def time_eval(self, n_datapoints: int, n_dims: int): self.objective.step(self.posterior, self.data).block_until_ready() - def time_grad(self, n_datapoints, n_dims): + def time_grad(self, n_datapoints: int, n_dims: int): jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) @@ -67,7 +67,7 @@ class Poisson: ] params = [[10, 100, 200, 500, 1000], [1, 2, 5]] - def setup(self, n_datapoints, n_dims): + def setup(self, n_datapoints: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, n_dims)) f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function @@ -80,8 +80,8 @@ def setup(self, n_datapoints, n_dims): self.objective = gpx.LogPosteriorDensity() self.posterior = self.prior * self.likelihood - def time_eval(self, n_datapoints, n_dims): + def time_eval(self, n_datapoints: int, n_dims: int): self.objective.step(self.posterior, self.data).block_until_ready() - def time_grad(self, n_datapoints, n_dims): + def time_grad(self, n_datapoints: int, n_dims: int): jax.block_until_ready(jax.grad(self.objective.step)(self.posterior, self.data)) diff --git a/benchmarks/predictions.py b/benchmarks/predictions.py index 19aa44171..eed35d66a 100644 --- a/benchmarks/predictions.py +++ b/benchmarks/predictions.py @@ -14,7 +14,7 @@ class Gaussian: ] params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] - def setup(self, n_test, n_dims): + def setup(self, n_test: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) self.y = jnp.sin(self.X[:, :1]) @@ -27,7 +27,7 @@ def setup(self, n_test, n_dims): key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) - def time_predict(self, n_test, n_dims): + def time_predict(self, n_test: int, n_dims: int): self.posterior.predict(test_inputs=self.xtest, train_data=self.data) @@ -38,7 +38,7 @@ class Bernoulli: ] params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] - def setup(self, n_test, n_dims): + def setup(self, n_test: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) self.y = jnp.sin(self.X[:, :1]) @@ -52,7 +52,7 @@ def setup(self, n_test, n_dims): key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) - def time_predict(self, n_test, n_dims): + def time_predict(self, n_test: int, n_dims: int): self.posterior.predict(test_inputs=self.xtest, train_data=self.data) @@ -63,7 +63,7 @@ class Poisson: ] params = [[100, 200, 500, 1000, 2000, 3000], [1, 2, 5]] - def setup(self, n_test, n_dims): + def setup(self, n_test: int, n_dims: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(100, n_dims)) f = lambda x: 2.0 * jnp.sin(3 * x) + 0.5 * x # latent function @@ -77,5 +77,5 @@ def setup(self, n_test, n_dims): key, subkey = jr.split(key) self.xtest = jr.normal(key=subkey, shape=(n_test, n_dims)) - def time_predict(self, n_test, n_dims): + def time_predict(self, n_test: int, n_dims: int): self.posterior.predict(test_inputs=self.xtest, train_data=self.data) diff --git a/benchmarks/sparse.py b/benchmarks/sparse.py index 2758b365f..759cac9bc 100644 --- a/benchmarks/sparse.py +++ b/benchmarks/sparse.py @@ -12,7 +12,7 @@ class Sparse: param_names = ["n_data", "n_inducing"] params = [[2000, 5000, 10000, 20000], [10, 20, 50, 100, 200]] - def setup(self, n_datapoints, n_inducing): + def setup(self, n_datapoints: int, n_inducing: int): key = jr.PRNGKey(123) self.X = jr.normal(key=key, shape=(n_datapoints, 1)) self.y = jnp.sin(self.X[:, :1]) @@ -29,8 +29,8 @@ def setup(self, n_datapoints, n_inducing): ) self.objective = gpx.CollapsedELBO(negative=True) - def time_eval(self, n_datapoints, n_dims): + def time_eval(self, n_datapoints: int, n_dims: int): self.objective(self.q, self.data) - def time_grad(self, n_datapoints, n_dims): + def time_grad(self, n_datapoints: int, n_dims: int): jax.grad(self.objective)(self.q, self.data) From 79da0624aa6ee172a9aa509bc1974512ae605cd9 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:24:01 +0200 Subject: [PATCH 37/76] Fix typo --- .github/workflows/benchmarks.yml | 2 +- tests/{integration_tests.py => test_end_to_end.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{integration_tests.py => test_end_to_end.py} (100%) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 94235c805..22501922e 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -39,7 +39,7 @@ jobs: run: asv machine --yes - name: Run benchmarks - uses: | + run: | cd benchmarks asv run --python PYTHON asv publish diff --git a/tests/integration_tests.py b/tests/test_end_to_end.py similarity index 100% rename from tests/integration_tests.py rename to tests/test_end_to_end.py From 92b993a9e4262b7cb0c7ade4a0d21f9f2cd94b83 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:25:59 +0200 Subject: [PATCH 38/76] Fix typo --- .github/workflows/integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 214243ba8..55101c14b 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -43,4 +43,4 @@ jobs: # Run the unit tests and build the coverage report - name: Run Integration Tests - run: poetry run python tests/integration_tests.py + run: poetry run python tests/test_end_to_end.py From 31290ca7974c237ab183df40a7dd6e18da0b9292 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:28:27 +0200 Subject: [PATCH 39/76] Add missing dep --- .github/workflows/benchmarks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 22501922e..845b66582 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -33,6 +33,7 @@ jobs: - name: Install dependencies run: | poetry install --all-extras --with dev + pip install asv pip install virtualenv - name: Set asv machine From 6e80a48fc4166a7f21d6685c7e6c8fc2653711d4 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:36:31 +0200 Subject: [PATCH 40/76] cdir --- .github/workflows/benchmarks.yml | 7 +++++-- README.md | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 94235c805..93609c894 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -34,12 +34,15 @@ jobs: run: | poetry install --all-extras --with dev pip install virtualenv + pip install asv - name: Set asv machine - run: asv machine --yes + run: | + cd benchmarks + asv machine --yes - name: Run benchmarks - uses: | + run: | cd benchmarks asv run --python PYTHON asv publish diff --git a/README.md b/README.md index ea95d3a45..f9469b2a1 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,10 @@ jupytext --to py:percent example.ipynb Let us import some dependencies and simulate a toy dataset $\mathcal{D}$. ```python +from jax import config + +config.update("jax_enable_x64", True) + import gpjax as gpx from jax import grad, jit import jax.numpy as jnp From b9e1646bb114fe5e18b791af2c3f3d23e0fbb688 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:38:57 +0200 Subject: [PATCH 41/76] Fix cdir --- .github/workflows/integration.yml | 2 +- tests/{test_end_to_end.py => integration_tests.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{test_end_to_end.py => integration_tests.py} (100%) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 55101c14b..214243ba8 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -43,4 +43,4 @@ jobs: # Run the unit tests and build the coverage report - name: Run Integration Tests - run: poetry run python tests/test_end_to_end.py + run: poetry run python tests/integration_tests.py diff --git a/tests/test_end_to_end.py b/tests/integration_tests.py similarity index 100% rename from tests/test_end_to_end.py rename to tests/integration_tests.py From 6aaeecf5d839831cd0140be81808915b0aaec516 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 18:42:27 +0200 Subject: [PATCH 42/76] Drop Python binary in benchmarks --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index c983ee01c..5fb05e2de 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -45,7 +45,7 @@ jobs: - name: Run benchmarks run: | cd benchmarks - asv run --python PYTHON + asv run asv publish - name: Deploy to benchmarks branch From 29cf8a25a75f1e452a9576732c40d139022cfe8a Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 26 Aug 2023 19:00:59 +0200 Subject: [PATCH 43/76] Hard JAX install --- .github/workflows/benchmarks.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 5fb05e2de..0886a0aed 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -20,19 +20,15 @@ jobs: uses: actions/checkout@v3.5.2 with: fetch-depth: 1 - - name: Install Poetry - uses: snok/install-poetry@v1.3.3 - with: - version: 1.4.0 - # Configure Poetry to use the virtual environment in the project - - name: Setup Poetry - run: | - poetry config virtualenvs.in-project true + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: "3.8" - name: Install dependencies run: | - poetry install --all-extras --with dev + pip install gpjax pip install asv pip install virtualenv pip install asv From 7d7d435b81647de7ed29a25973e1af1bf2b39209 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 06:12:51 +0200 Subject: [PATCH 44/76] Add packaging --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 0886a0aed..daf558662 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -29,7 +29,7 @@ jobs: - name: Install dependencies run: | pip install gpjax - pip install asv + pip install packaging pip install virtualenv pip install asv From 5675e2d8a8833ae22c83bd936f7819886e44dea7 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 06:24:33 +0200 Subject: [PATCH 45/76] Add poetry install --- .github/workflows/benchmarks.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index daf558662..4030be354 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -26,9 +26,17 @@ jobs: with: python-version: "3.8" + - name: Install and configure Poetry + uses: snok/install-poetry@v1 + with: + version: 1.2.2 + virtualenvs-create: false + virtualenvs-in-project: false + installer-parallel: true + - name: Install dependencies run: | - pip install gpjax + poetry install --all-extras --with dev pip install packaging pip install virtualenv pip install asv From 250a0ebfd5ac59cf3530e52ddf036303b2c10d4e Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 06:34:01 +0200 Subject: [PATCH 46/76] Add poetry install --- .github/workflows/benchmarks.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 4030be354..7b79a8c92 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -30,24 +30,26 @@ jobs: uses: snok/install-poetry@v1 with: version: 1.2.2 - virtualenvs-create: false + virtualenvs-create: true virtualenvs-in-project: false installer-parallel: true - name: Install dependencies run: | - poetry install --all-extras --with dev + poetry install --no-interaction --all-extras --with dev pip install packaging pip install virtualenv pip install asv - name: Set asv machine run: | + source .venv/bin/activate cd benchmarks asv machine --yes - name: Run benchmarks run: | + source .venv/bin/activate cd benchmarks asv run asv publish From 6bfe17961e4d267b625b0a3a61422fa0fa092978 Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 06:39:33 +0200 Subject: [PATCH 47/76] Add install to project --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 7b79a8c92..6878f21ef 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -31,7 +31,7 @@ jobs: with: version: 1.2.2 virtualenvs-create: true - virtualenvs-in-project: false + virtualenvs-in-project: true installer-parallel: true - name: Install dependencies From c82acc20eabe57ac42d1536f3a5b0487f1ac5aee Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 07:13:10 +0200 Subject: [PATCH 48/76] Add PYTHON path --- .github/workflows/benchmarks.yml | 7 ++++--- benchmarks/asv.conf.json | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 6878f21ef..b63185362 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -36,6 +36,7 @@ jobs: - name: Install dependencies run: | + pip install poetry poetry install --no-interaction --all-extras --with dev pip install packaging pip install virtualenv @@ -45,14 +46,14 @@ jobs: run: | source .venv/bin/activate cd benchmarks - asv machine --yes + poetry run asv machine --yes - name: Run benchmarks run: | source .venv/bin/activate cd benchmarks - asv run - asv publish + poetry run asv run --python PYTHON + poetry run asv publish - name: Deploy to benchmarks branch uses: peaceiris/actions-gh-pages@v3 diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 1d4353b13..68d7ea013 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -8,6 +8,7 @@ "PIP_NO_BUILD_ISOLATION=false python -m pip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" ], "branches": ["main"], + "dvcs": "git", "environment_type": "virtualenv", "show_commit_url": "https://github.com/jaxgaussianprocesses/gpjax/commit/main", From 3caa168444770518923714a5902d85b81ce86dad Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 07:16:58 +0200 Subject: [PATCH 49/76] Add PYTHON path --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index b63185362..d0e654983 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -52,7 +52,7 @@ jobs: run: | source .venv/bin/activate cd benchmarks - poetry run asv run --python PYTHON + poetry run asv run --show-stderr poetry run asv publish - name: Deploy to benchmarks branch From 268acc54eaa0aa3ed815542ecb7e64f61eb51a2b Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 07:31:19 +0200 Subject: [PATCH 50/76] Add MATRIX --- benchmarks/asv.conf.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 68d7ea013..84b7eaafe 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -8,7 +8,11 @@ "PIP_NO_BUILD_ISOLATION=false python -m pip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" ], "branches": ["main"], - + "matrix": { + "req": { + "poetry": [""] + } + }, "dvcs": "git", "environment_type": "virtualenv", "show_commit_url": "https://github.com/jaxgaussianprocesses/gpjax/commit/main", From 8052e3c8d3d754f849e7dff73669567357581d8f Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 07:37:21 +0200 Subject: [PATCH 51/76] Add interpreter --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index d0e654983..616e2d05b 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -52,7 +52,7 @@ jobs: run: | source .venv/bin/activate cd benchmarks - poetry run asv run --show-stderr + poetry run asv run --show-stderr --python ../../.venv/bin/python poetry run asv publish - name: Deploy to benchmarks branch From 4f0e31cbeeb1bece6a0919d8886781750823461e Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Mon, 28 Aug 2023 07:51:10 +0200 Subject: [PATCH 52/76] Drop workflow --- .github/workflows/benchmarks.yml | 63 -------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 .github/workflows/benchmarks.yml diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml deleted file mode 100644 index 616e2d05b..000000000 --- a/.github/workflows/benchmarks.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Benchmarks - -on: - push: - branches: [main] - schedule: - - cron: "0 2 * * *" - workflow_dispatch: - -jobs: - run-benchmarks: - name: Run benchmarks - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: ["ubuntu-latest"] - python-version: ["3.8"] - steps: - - name: Checkout the branch - uses: actions/checkout@v3.5.2 - with: - fetch-depth: 1 - - - name: Setup Python - uses: actions/setup-python@v3 - with: - python-version: "3.8" - - - name: Install and configure Poetry - uses: snok/install-poetry@v1 - with: - version: 1.2.2 - virtualenvs-create: true - virtualenvs-in-project: true - installer-parallel: true - - - name: Install dependencies - run: | - pip install poetry - poetry install --no-interaction --all-extras --with dev - pip install packaging - pip install virtualenv - pip install asv - - - name: Set asv machine - run: | - source .venv/bin/activate - cd benchmarks - poetry run asv machine --yes - - - name: Run benchmarks - run: | - source .venv/bin/activate - cd benchmarks - poetry run asv run --show-stderr --python ../../.venv/bin/python - poetry run asv publish - - - name: Deploy to benchmarks branch - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./.asv/html - publish_branch: benchmarks From f6aa6d4e586447b56dcb8841c3513cc439eff43d Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 1 Sep 2023 13:20:51 +0100 Subject: [PATCH 53/76] Implement CR feedback and change acquisition function naming Implemented minor CR feedback and renamed acquisition functions to utility functions to reflect the fact that the package will be used for general Bayesian decision making and not just Bayesian optimisation. --- gpjax/citation.py | 2 +- gpjax/decision_making/__init__.py | 30 +-- gpjax/decision_making/decision_maker.py | 185 +++++++++--------- .../__init__.py | 14 +- .../base.py | 26 +-- .../thompson_sampling.py | 30 ++- ...tion_maximizer.py => utility_maximizer.py} | 73 ++++--- gpjax/decision_making/utils.py | 2 +- .../test_decision_maker.py | 100 +++++----- .../test_decision_making/test_search_space.py | 2 +- .../test_continuous_functions.py | 2 +- .../test_non_conjugate_functions.py | 2 +- .../__init__.py | 0 .../test_base.py | 10 +- .../test_thompson_sampling.py | 74 ++++--- ...maximizer.py => test_utility_maximizer.py} | 64 +++--- tests/test_decision_making/utils.py | 20 +- 17 files changed, 311 insertions(+), 325 deletions(-) rename gpjax/decision_making/{acquisition_functions => utility_functions}/__init__.py (71%) rename gpjax/decision_making/{acquisition_functions => utility_functions}/base.py (75%) rename gpjax/decision_making/{acquisition_functions => utility_functions}/thompson_sampling.py (76%) rename gpjax/decision_making/{acquisition_maximizer.py => utility_maximizer.py} (60%) rename tests/test_decision_making/{test_acquisition_functions => test_utility_functions}/__init__.py (100%) rename tests/test_decision_making/{test_acquisition_functions => test_utility_functions}/test_base.py (77%) rename tests/test_decision_making/{test_acquisition_functions => test_utility_functions}/test_thompson_sampling.py (74%) rename tests/test_decision_making/{test_acquisition_maximizer.py => test_utility_maximizer.py} (73%) diff --git a/gpjax/citation.py b/gpjax/citation.py index 56202d2ab..2c29a6175 100644 --- a/gpjax/citation.py +++ b/gpjax/citation.py @@ -10,11 +10,11 @@ from jaxlib.xla_extension import PjitFunction from plum import dispatch -from gpjax.decision_making.acquisition_functions import ThompsonSampling from gpjax.decision_making.test_functions import ( Forrester, LogarithmicGoldsteinPrice, ) +from gpjax.decision_making.utility_functions import ThompsonSampling from gpjax.kernels import ( RFF, ArcCosine, diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index 50c7d551b..5c782a3a4 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -12,18 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from gpjax.decision_making.acquisition_functions import ( - AbstractAcquisitionFunctionBuilder, - AcquisitionFunction, - ThompsonSampling, -) -from gpjax.decision_making.acquisition_maximizer import ( - AbstractAcquisitionMaximizer, - ContinuousAcquisitionMaximizer, -) from gpjax.decision_making.decision_maker import ( AbstractDecisionMaker, - DecisionMaker, + UtilityDrivenDecisionMaker, ) from gpjax.decision_making.posterior_handler import PosteriorHandler from gpjax.decision_making.search_space import ( @@ -36,18 +27,27 @@ LogarithmicGoldsteinPrice, Quadratic, ) +from gpjax.decision_making.utility_functions import ( + AbstractUtilityFunctionBuilder, + ThompsonSampling, + UtilityFunction, +) +from gpjax.decision_making.utility_maximizer import ( + AbstractUtilityMaximizer, + ContinuousUtilityMaximizer, +) from gpjax.decision_making.utils import build_function_evaluator __all__ = [ - "AbstractAcquisitionFunctionBuilder", - "AbstractAcquisitionMaximizer", + "AbstractUtilityFunctionBuilder", + "AbstractUtilityMaximizer", "AbstractDecisionMaker", "AbstractSearchSpace", - "AcquisitionFunction", + "UtilityFunction", "build_function_evaluator", - "ContinuousAcquisitionMaximizer", + "ContinuousUtilityMaximizer", "ContinuousSearchSpace", - "DecisionMaker", + "UtilityDrivenDecisionMaker", "AbstractContinuousTestFunction", "Forrester", "LogarithmicGoldsteinPrice", diff --git a/gpjax/decision_making/decision_maker.py b/gpjax/decision_making/decision_maker.py index ddfff18b0..255a6b23a 100644 --- a/gpjax/decision_making/decision_maker.py +++ b/gpjax/decision_making/decision_maker.py @@ -16,10 +16,7 @@ ABC, abstractmethod, ) -from dataclasses import ( - dataclass, - field, -) +from dataclasses import dataclass from beartype.typing import ( Callable, @@ -30,12 +27,10 @@ import jax.random as jr from gpjax.dataset import Dataset -from gpjax.decision_making.acquisition_functions import ( - AbstractAcquisitionFunctionBuilder, -) -from gpjax.decision_making.acquisition_maximizer import AbstractAcquisitionMaximizer from gpjax.decision_making.posterior_handler import PosteriorHandler from gpjax.decision_making.search_space import AbstractSearchSpace +from gpjax.decision_making.utility_functions import AbstractUtilityFunctionBuilder +from gpjax.decision_making.utility_maximizer import AbstractUtilityMaximizer from gpjax.decision_making.utils import FunctionEvaluator from gpjax.gps import AbstractPosterior from gpjax.typing import ( @@ -48,28 +43,29 @@ @dataclass class AbstractDecisionMaker(ABC): """ - AbstractDecisionMaker abstract base class which handles the core decision loop. The - decision making loop is split into two key steps, `ask` and `tell`. The `ask` + AbstractDecisionMaker abstract base class which handles the core decision making + loop, where we sequentially decide on points to query our function of interest at. + The decision making loop is split into two key steps, `ask` and `tell`. The `ask` step is typically used to decide which point to query next. The `tell` step is - typically used to update models and datasets with newly queried points. + typically used to update models and datasets with newly queried points. These steps + can be combined in a 'run' loop which alternates between asking which point to query + next and telling the decision maker about the newly queried point having evaluated + the black-box function of interest at this point. Attributes: - search_space (AbstractSearchSpace): Search space which is being queried + search_space (AbstractSearchSpace): Search space over which we can evaluate the + function(s) of interest. posterior_handlers (Dict[str, PosteriorHandler]): Dictionary of posterior handlers, which are used to update posteriors throughout the decision making - loop. Tags are used to distinguish between posteriors. In a typical Bayesian - optimisation setup one of the tags will be `OBJECTIVE`, defined in + loop. Note that the word `posteriors` is used for consistency with GPJax, but these + objects are typically referred to as `models` in the model-based decision + making literature. Tags are used to distinguish between posteriors. In a typical + Bayesian optimisation setup one of the tags will be `OBJECTIVE`, defined in decision_making.utils. datasets (Dict[str, Dataset]): Dictionary of datasets, which are augmented with observations throughout the decision making loop. In a typical setup they are - also used to fit the posteriors, using the `posterior_handlers`. Tags are used + also used to update the posteriors, using the `posterior_handlers`. Tags are used to distinguish datasets, and correspond to tags in `posterior_handlers`. - acquisition_function_builder (AbstractAcquisitionFunctionBuilder): Object which - builds acquisition functions from posteriors and datasets, to decide where - to query next. In a typical Bayesian optimisation setup the point chosen to - be queried next is the point which maximizes the acquisition function. - acquisition_maximizer (AbstractAcquisitionMaximizer): Object which maximizes - acquisition functions over the search space. key (KeyArray): JAX random key, used to generate random numbers. post_ask (List[Callable]): List of functions to be executed after each ask step. post_tell (List[Callable]): List of functions to be executed after each tell @@ -79,64 +75,13 @@ class AbstractDecisionMaker(ABC): search_space: AbstractSearchSpace posterior_handlers: Dict[str, PosteriorHandler] datasets: Dict[str, Dataset] - acquisition_function_builder: AbstractAcquisitionFunctionBuilder - acquisition_maximizer: AbstractAcquisitionMaximizer key: KeyArray - post_ask: List[Callable] = field( - default_factory=list - ) # Specific type is List[Callable[[DecisionMaker, Float[Array, ["1 D"]]], None]] but causes Beartype issues - post_tell: List[Callable] = field( - default_factory=list - ) # Specific type is List[Callable[[DecisionMaker], None]] but causes Beartype issues - - @abstractmethod - def ask(self, key: KeyArray) -> Float[Array, "1 D"]: - """ - In a typical decision making setup this will use the - `acquisition_function_builder` to form an acquisition function and then return - the point which maximizes the acquisition function using the - `acquisition_maximizer` as the point to be queried next. - - Args: - key (KeyArray): JAX PRNG key for controlling random state. - - Returns: - Float[Array, "1 D"]: Point to be queried next - """ - raise NotImplementedError - - @abstractmethod - def tell(self, observation_datasets: Mapping[str, Dataset], key: KeyArray): - """ - Tell decision maker about new observations. In a typical decision making setup - we will update the datasets and posteriors with the new observations. - - Args: - observation_datasets (Mapping[str, Dataset]): Dictionary of datasets - containing new observations. Tags are used to distinguish datasets, and - correspond to tags in `posterior_handlers` in a typical setup. - key (KeyArray): JAX PRNG key for controlling random state. - """ - raise NotImplementedError - - -@dataclass -class DecisionMaker(AbstractDecisionMaker): - """ - DecisionMaker class which handles the core decision making loop in a typical setup. The - decision making loop is split into two key steps, `ask` and `tell`. The `ask` - step forms an `AcquisitionFunction` from the current `posteriors` and `datasets` and - returns the point which maximises it. It also stores the formed acquisition function - under the attribute `self.current_acquisition_function` so that it can be called, - for instance for plotting, after the `ask` function has been called. The `tell` step - adds a newly queried point to the `datasets` and updates the `posteriors`. - - This can be run as a typical ask-tell loop, or the `run` method can be used to run - the decision making loop for a fixed number of steps. Moreover, the `run` method executes - the functions in `post_ask` and `post_tell` after each ask and tell step - respectively. This enables the user to add custom functionality, such as the ability - to plot values of interest during the optimization process. - """ + post_ask: List[ + Callable + ] # Specific type is List[Callable[[AbstractDecisionMaker, Float[Array, ["1 D"]]], None]] but causes Beartype issues + post_tell: List[ + Callable + ] # Specific type is List[Callable[[AbstractDecisionMaker], None]] but causes Beartype issues def __post_init__(self): """ @@ -159,31 +104,18 @@ def __post_init__(self): self.datasets[tag], optimize=True, key=self.key ) + @abstractmethod def ask(self, key: KeyArray) -> Float[Array, "1 D"]: """ - Get updated acquisition function and return the point which maximises it. This - method also stores the acquisition function in - `self.current_acquisition_function` so that it can be accessed after the ask - function has been called. This is useful for non-deterministic acquisition - functions, which will differ between calls to `ask` due to the splitting of - `self.key`. + Get the point to be queried next. Args: key (KeyArray): JAX PRNG key for controlling random state. Returns: - Float[Array, "1 D"]: Point to be queried next. + Float[Array, "1 D"]: Point to be queried next """ - self.current_acquisition_function = ( - self.acquisition_function_builder.build_acquisition_function( - self.posteriors, self.datasets, key - ) - ) - - key, _ = jr.split(key) - return self.acquisition_maximizer.maximize( - self.current_acquisition_function, self.search_space, key - ) + raise NotImplementedError def tell(self, observation_datasets: Mapping[str, Dataset], key: KeyArray): """ @@ -252,3 +184,66 @@ def run( post_tell_method(self) return self.datasets + + +@dataclass +class UtilityDrivenDecisionMaker(AbstractDecisionMaker): + """ + UtilityDrivenDecisionMaker class which handles the core decision making loop in a + typical model-based decision making setup. In this setup we use surrogate model(s) + for the function(s) of interest, and define a utility function (often called the + 'acquisition function' in the context of Bayesian optimisation) which characterises + how useful it would be to query a given point within the search space given the data + we have observed so far. This can then be used to decide which point(s) to query + next. + + The decision making loop is split into two key steps, `ask` and `tell`. The `ask` + step forms a `UtilityFunction` from the current `posteriors` and `datasets` and + returns the point which maximises it. It also stores the formed utility function + under the attribute `self.current_utility_function` so that it can be called, + for instance for plotting, after the `ask` function has been called. The `tell` step + adds a newly queried point to the `datasets` and updates the `posteriors`. + + This can be run as a typical ask-tell loop, or the `run` method can be used to run + the decision making loop for a fixed number of steps. Moreover, the `run` method executes + the functions in `post_ask` and `post_tell` after each ask and tell step + respectively. This enables the user to add custom functionality, such as the ability + to plot values of interest during the optimization process. + + Attributes: + utility_function_builder (AbstractUtilityFunctionBuilder): Object which + builds utility functions from posteriors and datasets, to decide where + to query next. In a typical Bayesian optimisation setup the point chosen to + be queried next is the point which maximizes the utility function. + utility_maximizer (AbstractUtilityMaximizer): Object which maximizes + utility functions over the search space. + """ + + utility_function_builder: AbstractUtilityFunctionBuilder + utility_maximizer: AbstractUtilityMaximizer + + def ask(self, key: KeyArray) -> Float[Array, "1 D"]: + """ + Get updated utility function and return the point which maximises it. This + method also stores the utility function in + `self.current_utility_function` so that it can be accessed after the ask + function has been called. This is useful for non-deterministic utility + functions, which will differ between calls to `ask` due to the splitting of + `self.key`. + + Args: + key (KeyArray): JAX PRNG key for controlling random state. + + Returns: + Float[Array, "1 D"]: Point to be queried next. + """ + self.current_utility_function = ( + self.utility_function_builder.build_utility_function( + self.posteriors, self.datasets, key + ) + ) + + key, _ = jr.split(key) + return self.utility_maximizer.maximize( + self.current_utility_function, self.search_space, key + ) diff --git a/gpjax/decision_making/acquisition_functions/__init__.py b/gpjax/decision_making/utility_functions/__init__.py similarity index 71% rename from gpjax/decision_making/acquisition_functions/__init__.py rename to gpjax/decision_making/utility_functions/__init__.py index 9c986fff6..dbf8a9577 100644 --- a/gpjax/decision_making/acquisition_functions/__init__.py +++ b/gpjax/decision_making/utility_functions/__init__.py @@ -12,16 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from gpjax.decision_making.acquisition_functions.base import ( - AbstractAcquisitionFunctionBuilder, - AcquisitionFunction, -) -from gpjax.decision_making.acquisition_functions.thompson_sampling import ( - ThompsonSampling, +from gpjax.decision_making.utility_functions.base import ( + AbstractUtilityFunctionBuilder, + UtilityFunction, ) +from gpjax.decision_making.utility_functions.thompson_sampling import ThompsonSampling __all__ = [ - "AcquisitionFunction", - "AbstractAcquisitionFunctionBuilder", + "UtilityFunction", + "AbstractUtilityFunctionBuilder", "ThompsonSampling", ] diff --git a/gpjax/decision_making/acquisition_functions/base.py b/gpjax/decision_making/utility_functions/base.py similarity index 75% rename from gpjax/decision_making/acquisition_functions/base.py rename to gpjax/decision_making/utility_functions/base.py index 59cfcbf8e..c06ffc9db 100644 --- a/gpjax/decision_making/acquisition_functions/base.py +++ b/gpjax/decision_making/utility_functions/base.py @@ -32,17 +32,17 @@ KeyArray, ) -AcquisitionFunction = Callable[[Float[Array, "N D"]], Float[Array, "N 1"]] +UtilityFunction = Callable[[Float[Array, "N D"]], Float[Array, "N 1"]] """ -Type alias for acquisition functions, which take an array of points of shape $`[N, D]`$ -and return the value of the acquisition function at each point in an array of shape $`[N, 1]`$. +Type alias for utility functions, which take an array of points of shape $`[N, D]`$ +and return the value of the utility function at each point in an array of shape $`[N, 1]`$. """ @dataclass -class AbstractAcquisitionFunctionBuilder(ABC): +class AbstractUtilityFunctionBuilder(ABC): """ - Abstract class for building acquisition functions. + Abstract class for building utility functions. """ def check_objective_present( @@ -56,9 +56,9 @@ def check_objective_present( Args: posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be - used to form the acquisition function. + used to form the utility function. datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used - to form the acquisition function. + to form the utility function. Raises: ValueError: If the objective posterior or dataset are not present in the @@ -70,24 +70,24 @@ def check_objective_present( raise ValueError("Objective dataset not found in datasets") @abstractmethod - def build_acquisition_function( + def build_utility_function( self, posteriors: Mapping[str, AbstractPosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> AcquisitionFunction: + ) -> UtilityFunction: """ - Build an `AcquisitionFunction` from a set of posteriors and datasets. + Build a `UtilityFunction` from a set of posteriors and datasets. Args: posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be - used to form the acquisition function. + used to form the utility function. datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used - to form the acquisition function. + to form the utility function. key (KeyArray): JAX PRNG key used for random number generation. Returns: - AcquisitionFunction: Acquisition function to be *maximised* in order to + UtilityFunction: Utility function to be *maximised* in order to decide which point to query next. """ raise NotImplementedError diff --git a/gpjax/decision_making/acquisition_functions/thompson_sampling.py b/gpjax/decision_making/utility_functions/thompson_sampling.py similarity index 76% rename from gpjax/decision_making/acquisition_functions/thompson_sampling.py rename to gpjax/decision_making/utility_functions/thompson_sampling.py index 129cb4e97..6ef765f5f 100644 --- a/gpjax/decision_making/acquisition_functions/thompson_sampling.py +++ b/gpjax/decision_making/utility_functions/thompson_sampling.py @@ -17,9 +17,9 @@ from beartype.typing import Mapping from gpjax.dataset import Dataset -from gpjax.decision_making.acquisition_functions.base import ( - AbstractAcquisitionFunctionBuilder, - AcquisitionFunction, +from gpjax.decision_making.utility_functions.base import ( + AbstractUtilityFunctionBuilder, + UtilityFunction, ) from gpjax.decision_making.utils import OBJECTIVE from gpjax.gps import ConjugatePosterior @@ -27,12 +27,12 @@ @dataclass -class ThompsonSampling(AbstractAcquisitionFunctionBuilder): +class ThompsonSampling(AbstractUtilityFunctionBuilder): """ - Form an acquisition function by drawing an approximate sample from the posterior, + Form a utility function by drawing an approximate sample from the posterior, using decoupled sampling as introduced in [Wilson et. al. (2020)](https://arxiv.org/abs/2002.09309). Note that we return the *negative* of the - sample as the acquisition function, as acquisition functions are *maximised*. + sample as the utility function, as utility functions are *maximised*. Attributes: num_features (int): The number of random Fourier features to use when drawing @@ -47,30 +47,30 @@ def __post_init__(self): "The number of random Fourier features must be a positive integer." ) - def build_acquisition_function( + def build_utility_function( self, posteriors: Mapping[str, ConjugatePosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> AcquisitionFunction: + ) -> UtilityFunction: """ Draw an approximate sample from the posterior of the objective model and return - the *negative* of this sample as an acquisition function, as acquisition functions + the *negative* of this sample as a utility function, as utility functions are *maximised*. Args: posteriors (Mapping[str, AbstractPosterior]): Dictionary of posteriors to be - used to form the acquisition function. One of the posteriors must correspond + used to form the utility function. One of the posteriors must correspond to the `OBJECTIVE` key, as we sample from the objective posterior to form - the acquisition function. + the utility function. datasets (Mapping[str, Dataset]): Dictionary of datasets which may be used - to form the acquisition function. Keys in `datasets` should correspond to + to form the utility function. Keys in `datasets` should correspond to keys in `posteriors`. One of the datasets must correspond to the `OBJECTIVE` key. key (KeyArray): JAX PRNG key used for random number generation. Returns: - AcquisitionFunction: An appproximate sample from the objective model + UtilityFunction: An appproximate sample from the objective model posterior to to be *maximised* in order to decide which point to query next. """ @@ -90,6 +90,4 @@ def build_acquisition_function( num_features=self.num_features, ) - return lambda x: -1.0 * thompson_sample( - x - ) # Acquisition functions are *maximised* + return lambda x: -1.0 * thompson_sample(x) # Utility functions are *maximised* diff --git a/gpjax/decision_making/acquisition_maximizer.py b/gpjax/decision_making/utility_maximizer.py similarity index 60% rename from gpjax/decision_making/acquisition_maximizer.py rename to gpjax/decision_making/utility_maximizer.py index 1f75f5ced..ff0871f5d 100644 --- a/gpjax/decision_making/acquisition_maximizer.py +++ b/gpjax/decision_making/utility_maximizer.py @@ -22,11 +22,11 @@ import jax.random as jr from jaxopt import ScipyBoundedMinimize -from gpjax.decision_making.acquisition_functions import AcquisitionFunction from gpjax.decision_making.search_space import ( AbstractSearchSpace, ContinuousSearchSpace, ) +from gpjax.decision_making.utility_functions import UtilityFunction from gpjax.typing import ( Array, Float, @@ -36,60 +36,58 @@ def _get_discrete_maximizer( - query_points: Float[Array, "N D"], acquisition_function: AcquisitionFunction + query_points: Float[Array, "N D"], utility_function: UtilityFunction ) -> Float[Array, "1 D"]: - """Get the point which maximises the acquisition function evaluated at a given set of points. + """Get the point which maximises the utility function evaluated at a given set of points. Args: query_points (Float[Array, "N D"]): Set of points at which to evaluate the - acquisition function. - acquisition_function (AcquisitionFunction): Acquisition function - to evaluate at `query_points`. + utility function. + utility_function (UtilityFunction): Utility function to evaluate at `query_points`. Returns: - Float[Array, "1 D"]: Point in `query_points` which maximises the acquisition - function. + Float[Array, "1 D"]: Point in `query_points` which maximises the utility function. """ - acquisition_function_values = acquisition_function(query_points) - max_acquisition_function_value_idx = jnp.argmax( - acquisition_function_values, axis=0, keepdims=True + utility_function_values = utility_function(query_points) + max_utility_function_value_idx = jnp.argmax( + utility_function_values, axis=0, keepdims=True ) best_sample_point = jnp.take_along_axis( - query_points, max_acquisition_function_value_idx, axis=0 + query_points, max_utility_function_value_idx, axis=0 ) return best_sample_point @dataclass -class AbstractAcquisitionMaximizer(ABC): - """Abstract base class for acquisition function maximizers.""" +class AbstractUtilityMaximizer(ABC): + """Abstract base class for utility function maximizers.""" @abstractmethod def maximize( self, - acquisition_function: AcquisitionFunction, + utility_function: UtilityFunction, search_space: AbstractSearchSpace, key: KeyArray, ) -> Float[Array, "1 D"]: - """Maximize the given acquisition function over the search space provided. + """Maximize the given utility function over the search space provided. Args: - acquisition_function (AcquisitionFunction): Acquisition function to be + utility_function (UtilityFunction): Utility function to be maximized. search_space (AbstractSearchSpace): Search space over which to maximize - the acquisition function. + the utility function. key (KeyArray): JAX PRNG key. Returns: - Float[Array, "1 D"]: Point at which the acquisition function is maximized. + Float[Array, "1 D"]: Point at which the utility function is maximized. """ raise NotImplementedError @dataclass -class ContinuousAcquisitionMaximizer(AbstractAcquisitionMaximizer): - """The `ContinuousAcquisitionMaximizer` class is used to maximize acquisition - functions over the continuous domain with L-BFGS-B. First we sample the acquisition +class ContinuousUtilityMaximizer(AbstractUtilityMaximizer): + """The `ContinuousUtilityMaximizer` class is used to maximize utility + functions over the continuous domain with L-BFGS-B. First we sample the utility function at `num_initial_samples` points from the search space, and then we run L-BFGS-B from the best of these initial points. We run this process `num_restarts` number of times, each time sampling a different random set of @@ -111,11 +109,11 @@ def __post_init__(self): def maximize( self, - acquisition_function: AcquisitionFunction, + utility_function: UtilityFunction, search_space: ContinuousSearchSpace, key: KeyArray, ) -> Float[Array, "1 D"]: - max_observed_acquisition_function_value = None + max_observed_utility_function_value = None maximizer = None for _ in range(self.num_restarts): @@ -124,36 +122,31 @@ def maximize( self.num_initial_samples, key=key ) best_initial_sample_point = _get_discrete_maximizer( - initial_sample_points, acquisition_function + initial_sample_points, utility_function ) - def _scalar_acquisition_function(x: Float[Array, "1 D"]) -> ScalarFloat: + def _scalar_utility_function(x: Float[Array, "1 D"]) -> ScalarFloat: """ The Jaxopt minimizer requires a function which returns a scalar. It calls the - acquisition function with one point at a time, so the acquisition function + utility function with one point at a time, so the utility function returns an array of shape [1, 1], so we index to return a scalar. Note that - we also return the negative of the acquisition function - this is because - acquisition functions should be *maximimized* but the Jaxopt minimizer + we also return the negative of the utility function - this is because + utility functions should be *maximimized* but the Jaxopt minimizer minimizes functions. """ - return -acquisition_function(x)[0][0] + return -utility_function(x)[0][0] lbfgsb = ScipyBoundedMinimize( - fun=_scalar_acquisition_function, method="l-bfgs-b" + fun=_scalar_utility_function, method="l-bfgs-b" ) bounds = (search_space.lower_bounds, search_space.upper_bounds) optimized_point = lbfgsb.run( best_initial_sample_point, bounds=bounds ).params - optimized_acquisition_function_value = _scalar_acquisition_function( - optimized_point - ) - if (max_observed_acquisition_function_value is None) or ( - optimized_acquisition_function_value - > max_observed_acquisition_function_value + optimized_utility_function_value = _scalar_utility_function(optimized_point) + if (max_observed_utility_function_value is None) or ( + optimized_utility_function_value > max_observed_utility_function_value ): - max_observed_acquisition_function_value = ( - optimized_acquisition_function_value - ) + max_observed_utility_function_value = optimized_utility_function_value maximizer = optimized_point return maximizer diff --git a/gpjax/decision_making/utils.py b/gpjax/decision_making/utils.py index 55087c172..9af19de32 100644 --- a/gpjax/decision_making/utils.py +++ b/gpjax/decision_making/utils.py @@ -26,7 +26,7 @@ OBJECTIVE: Final[str] = "OBJECTIVE" """ -Tag for the objective dataset/function in standard acquisition functions. +Tag for the objective dataset/function in standard utility functions. """ diff --git a/tests/test_decision_making/test_decision_maker.py b/tests/test_decision_making/test_decision_maker.py index 235b5bc35..dad2340e1 100644 --- a/tests/test_decision_making/test_decision_maker.py +++ b/tests/test_decision_making/test_decision_maker.py @@ -23,16 +23,9 @@ import gpjax as gpx from gpjax.dataset import Dataset -from gpjax.decision_making.acquisition_functions import ( - AbstractAcquisitionFunctionBuilder, -) -from gpjax.decision_making.acquisition_maximizer import ( - AbstractAcquisitionMaximizer, - ContinuousAcquisitionMaximizer, -) from gpjax.decision_making.decision_maker import ( AbstractDecisionMaker, - DecisionMaker, + UtilityDrivenDecisionMaker, ) from gpjax.decision_making.posterior_handler import PosteriorHandler from gpjax.decision_making.search_space import ( @@ -40,12 +33,17 @@ ContinuousSearchSpace, ) from gpjax.decision_making.test_functions import Quadratic +from gpjax.decision_making.utility_functions import AbstractUtilityFunctionBuilder +from gpjax.decision_making.utility_maximizer import ( + AbstractUtilityMaximizer, + ContinuousUtilityMaximizer, +) from gpjax.decision_making.utils import ( OBJECTIVE, build_function_evaluator, ) from gpjax.typing import KeyArray -from tests.test_decision_making.utils import QuadraticAcquisitionFunctionBuilder +from tests.test_decision_making.utils import QuadraticUtilityFunctionBuilder CONSTRAINT = "CONSTRAINT" @@ -77,13 +75,13 @@ def posterior_handler() -> PosteriorHandler: @pytest.fixture -def acquisition_function_builder() -> AbstractAcquisitionFunctionBuilder: - return QuadraticAcquisitionFunctionBuilder() +def utility_function_builder() -> AbstractUtilityFunctionBuilder: + return QuadraticUtilityFunctionBuilder() @pytest.fixture -def acquisition_maximizer() -> AbstractAcquisitionMaximizer: - return ContinuousAcquisitionMaximizer(num_initial_samples=1000, num_restarts=1) +def utility_maximizer() -> AbstractUtilityMaximizer: + return ContinuousUtilityMaximizer(num_initial_samples=1000, num_restarts=1) def get_dataset(num_points: int, key: KeyArray) -> Dataset: @@ -103,21 +101,23 @@ def test_abstract_decision_maker_raises_error(): def test_invalid_tags_raises_error( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler} dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) datasets = {"CONSTRAINT": dataset} # Dataset tag doesn't match posterior tag with pytest.raises(ValueError): - DecisionMaker( + UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) @@ -127,21 +127,23 @@ def test_invalid_tags_raises_error( def test_initialisation_optimizes_posterior_hyperparameters( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) constraint_dataset = get_dataset(num_points=5, key=jr.PRNGKey(10)) datasets = {"OBJECTIVE": objective_dataset, CONSTRAINT: constraint_dataset} - decision_maker = DecisionMaker( + decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) # Assert kernel hyperparameters get changed from their initial values assert decision_maker.posteriors[OBJECTIVE].prior.kernel.lengthscale != jnp.array( @@ -168,26 +170,28 @@ def test_initialisation_optimizes_posterior_hyperparameters( def test_decision_maker_ask( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler} objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) datasets = {"OBJECTIVE": objective_dataset} - decision_maker = DecisionMaker( + decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) initial_decision_maker_key = decision_maker.key query_point = decision_maker.ask(key=key) assert query_point.shape == (1, 1) assert jnp.allclose(query_point, jnp.array([[0.5]]), atol=1e-5) - assert decision_maker.current_acquisition_function is not None + assert decision_maker.current_utility_function is not None assert ( decision_maker.key == initial_decision_maker_key ).all() # Ensure decision maker key is unchanged @@ -199,8 +203,8 @@ def test_decision_maker_ask( def test_decision_maker_tell_with_inconsistent_observations_raises_error( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} @@ -210,13 +214,15 @@ def test_decision_maker_tell_with_inconsistent_observations_raises_error( "OBJECTIVE": initial_objective_dataset, CONSTRAINT: initial_constraint_dataset, } - decision_maker = DecisionMaker( + decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) mock_objective_observation = get_dataset(num_points=1, key=jr.PRNGKey(1)) mock_constraint_observation = get_dataset(num_points=1, key=jr.PRNGKey(2)) @@ -234,8 +240,8 @@ def test_decision_maker_tell_with_inconsistent_observations_raises_error( def test_decision_maker_tell_updates_datasets_and_models( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} @@ -245,13 +251,15 @@ def test_decision_maker_tell_updates_datasets_and_models( "OBJECTIVE": initial_objective_dataset, CONSTRAINT: initial_constraint_dataset, } - decision_maker = DecisionMaker( + decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) initial_decision_maker_key = decision_maker.key initial_objective_posterior = decision_maker.posteriors[OBJECTIVE] @@ -295,8 +303,8 @@ def test_decision_maker_tell_updates_datasets_and_models( def test_decision_maker_run( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - acquisition_function_builder: AbstractAcquisitionFunctionBuilder, - acquisition_maximizer: AbstractAcquisitionMaximizer, + utility_function_builder: AbstractUtilityFunctionBuilder, + utility_maximizer: AbstractUtilityMaximizer, n_steps: int, ): key = jr.PRNGKey(42) @@ -305,13 +313,15 @@ def test_decision_maker_run( datasets = { "OBJECTIVE": initial_objective_dataset, } - decision_maker = DecisionMaker( + decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, datasets=datasets, - acquisition_function_builder=acquisition_function_builder, - acquisition_maximizer=acquisition_maximizer, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, key=key, + post_ask=[], + post_tell=[], ) initial_decision_maker_key = decision_maker.key black_box_fn = Quadratic() @@ -324,7 +334,7 @@ def test_decision_maker_run( assert query_datasets[OBJECTIVE].n == 5 + n_steps assert ( jnp.abs(query_datasets[OBJECTIVE].X[-n_steps:] - jnp.array([[0.5]])) < 1e-5 - ).all() # Ensure we're querying the correct point in our dummy acquisition function at each step + ).all() # Ensure we're querying the correct point in our dummy utility function at each step assert ( decision_maker.key != initial_decision_maker_key ).all() # Ensure decision maker key gets updated diff --git a/tests/test_decision_making/test_search_space.py b/tests/test_decision_making/test_search_space.py index 49bac87ab..95c47f8bb 100644 --- a/tests/test_decision_making/test_search_space.py +++ b/tests/test_decision_making/test_search_space.py @@ -13,7 +13,7 @@ # limitations under the License. # ============================================================================== from beartype.roar import BeartypeCallHintParamViolation -from jax.config import config +from jax import config import jax.numpy as jnp import jax.random as jr from jaxtyping import ( diff --git a/tests/test_decision_making/test_test_functions/test_continuous_functions.py b/tests/test_decision_making/test_test_functions/test_continuous_functions.py index 7b410f815..6272a6694 100644 --- a/tests/test_decision_making/test_test_functions/test_continuous_functions.py +++ b/tests/test_decision_making/test_test_functions/test_continuous_functions.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config config.update("jax_enable_x64", True) diff --git a/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py b/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py index 837abdbfd..f6d999b5c 100644 --- a/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py +++ b/tests/test_decision_making/test_test_functions/test_non_conjugate_functions.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config config.update("jax_enable_x64", True) diff --git a/tests/test_decision_making/test_acquisition_functions/__init__.py b/tests/test_decision_making/test_utility_functions/__init__.py similarity index 100% rename from tests/test_decision_making/test_acquisition_functions/__init__.py rename to tests/test_decision_making/test_utility_functions/__init__.py diff --git a/tests/test_decision_making/test_acquisition_functions/test_base.py b/tests/test_decision_making/test_utility_functions/test_base.py similarity index 77% rename from tests/test_decision_making/test_acquisition_functions/test_base.py rename to tests/test_decision_making/test_utility_functions/test_base.py index b71831ef3..c38a458f0 100644 --- a/tests/test_decision_making/test_acquisition_functions/test_base.py +++ b/tests/test_decision_making/test_utility_functions/test_base.py @@ -13,16 +13,14 @@ # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config import pytest -from gpjax.decision_making.acquisition_functions.base import ( - AbstractAcquisitionFunctionBuilder, -) +from gpjax.decision_making.utility_functions.base import AbstractUtilityFunctionBuilder config.update("jax_enable_x64", True) -def test_abstract_acquisition_function_builder(): +def test_abstract_utility_function_builder(): with pytest.raises(TypeError): - AbstractAcquisitionFunctionBuilder() + AbstractUtilityFunctionBuilder() diff --git a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py b/tests/test_decision_making/test_utility_functions/test_thompson_sampling.py similarity index 74% rename from tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py rename to tests/test_decision_making/test_utility_functions/test_thompson_sampling.py index 0d1980fe5..2ffd41ffe 100644 --- a/tests/test_decision_making/test_acquisition_functions/test_thompson_sampling.py +++ b/tests/test_decision_making/test_utility_functions/test_thompson_sampling.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config config.update("jax_enable_x64", True) @@ -22,14 +22,12 @@ import pytest from gpjax.dataset import Dataset -from gpjax.decision_making.acquisition_functions.thompson_sampling import ( - ThompsonSampling, -) from gpjax.decision_making.test_functions.continuous_functions import ( AbstractContinuousTestFunction, Forrester, LogarithmicGoldsteinPrice, ) +from gpjax.decision_making.utility_functions.thompson_sampling import ThompsonSampling from gpjax.decision_making.utils import OBJECTIVE from gpjax.gps import ( ConjugatePosterior, @@ -74,8 +72,8 @@ def test_thompson_sampling_no_objective_posterior_raises_error(): posteriors = {"CONSTRAINT": posterior} datasets = {OBJECTIVE: dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_features=100) - ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=100) + ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -91,8 +89,8 @@ def test_thompson_sampling_no_objective_dataset_raises_error(): posteriors = {OBJECTIVE: posterior} datasets = {"CONSTRAINT": dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_features=100) - ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=100) + ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -108,8 +106,8 @@ def test_thompson_sampling_non_conjugate_posterior_raises_error(): posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_features=100) - ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=100) + ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -126,8 +124,8 @@ def test_thompson_sampling_invalid_rff_num_raises_error(num_rff_features: int): posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} with pytest.raises(ValueError): - ts_acquisition_builder = ThompsonSampling(num_features=num_rff_features) - ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=num_rff_features) + ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) @@ -141,7 +139,7 @@ def test_thompson_sampling_invalid_rff_num_raises_error(num_rff_features: int): @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_thompson_sampling_acquisition_function_correct_shapes( +def test_thompson_sampling_utility_function_correct_shapes( test_target_function: AbstractContinuousTestFunction, num_test_points: int, key: KeyArray, @@ -150,14 +148,14 @@ def test_thompson_sampling_acquisition_function_correct_shapes( posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - ts_acquisition_builder = ThompsonSampling(num_features=100) - ts_acquisition_function = ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=100) + ts_utility_function = ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) test_key, _ = jr.split(key) test_X = test_target_function.generate_test_points(num_test_points, test_key) - ts_acquisition_function_values = ts_acquisition_function(test_X) - assert ts_acquisition_function_values.shape == (num_test_points, 1) + ts_utility_function_values = ts_utility_function(test_X) + assert ts_utility_function_values.shape == (num_test_points, 1) @pytest.mark.parametrize( @@ -169,7 +167,7 @@ def test_thompson_sampling_acquisition_function_correct_shapes( @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_thompson_sampling_acquisition_function_same_key_same_function( +def test_thompson_sampling_utility_function_same_key_same_function( test_target_function: AbstractContinuousTestFunction, num_test_points: int, key: KeyArray, @@ -178,23 +176,21 @@ def test_thompson_sampling_acquisition_function_same_key_same_function( posterior = generate_dummy_conjugate_posterior(dataset) posteriors = {OBJECTIVE: posterior} datasets = {OBJECTIVE: dataset} - ts_acquisition_builder_one = ThompsonSampling(num_features=100) - ts_acquisition_builder_two = ThompsonSampling(num_features=100) - ts_acquisition_function_one = ts_acquisition_builder_one.build_acquisition_function( + ts_utility_builder_one = ThompsonSampling(num_features=100) + ts_utility_builder_two = ThompsonSampling(num_features=100) + ts_utility_function_one = ts_utility_builder_one.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) - ts_acquisition_function_two = ts_acquisition_builder_two.build_acquisition_function( + ts_utility_function_two = ts_utility_builder_two.build_utility_function( posteriors=posteriors, datasets=datasets, key=key ) test_key, _ = jr.split(key) test_X = test_target_function.generate_test_points(num_test_points, test_key) - ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) - ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) - assert isinstance(ts_acquisition_function_one, Callable) - assert isinstance(ts_acquisition_function_two, Callable) - assert ( - ts_acquisition_function_one_values == ts_acquisition_function_two_values - ).all() + ts_utility_function_one_values = ts_utility_function_one(test_X) + ts_utility_function_two_values = ts_utility_function_two(test_X) + assert isinstance(ts_utility_function_one, Callable) + assert isinstance(ts_utility_function_two, Callable) + assert (ts_utility_function_one_values == ts_utility_function_two_values).all() @pytest.mark.parametrize( @@ -206,7 +202,7 @@ def test_thompson_sampling_acquisition_function_same_key_same_function( @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort -def test_thompson_sampling_acquisition_function_different_key_different_function( +def test_thompson_sampling_utility_function_different_key_different_function( test_target_function: AbstractContinuousTestFunction, num_test_points: int, key: KeyArray, @@ -217,19 +213,17 @@ def test_thompson_sampling_acquisition_function_different_key_different_function datasets = {OBJECTIVE: dataset} sample_one_key = key sample_two_key, _ = jr.split(key) - ts_acquisition_builder = ThompsonSampling(num_features=100) - ts_acquisition_function_one = ts_acquisition_builder.build_acquisition_function( + ts_utility_builder = ThompsonSampling(num_features=100) + ts_utility_function_one = ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=sample_one_key ) - ts_acquisition_function_two = ts_acquisition_builder.build_acquisition_function( + ts_utility_function_two = ts_utility_builder.build_utility_function( posteriors=posteriors, datasets=datasets, key=sample_two_key ) test_key, _ = jr.split(sample_two_key) test_X = test_target_function.generate_test_points(num_test_points, test_key) - ts_acquisition_function_one_values = ts_acquisition_function_one(test_X) - ts_acquisition_function_two_values = ts_acquisition_function_two(test_X) - assert isinstance(ts_acquisition_function_one, Callable) - assert isinstance(ts_acquisition_function_two, Callable) - assert not ( - ts_acquisition_function_one_values == ts_acquisition_function_two_values - ).all() + ts_utility_function_one_values = ts_utility_function_one(test_X) + ts_utility_function_two_values = ts_utility_function_two(test_X) + assert isinstance(ts_utility_function_one, Callable) + assert isinstance(ts_utility_function_two, Callable) + assert not (ts_utility_function_one_values == ts_utility_function_two_values).all() diff --git a/tests/test_decision_making/test_acquisition_maximizer.py b/tests/test_decision_making/test_utility_maximizer.py similarity index 73% rename from tests/test_decision_making/test_acquisition_maximizer.py rename to tests/test_decision_making/test_utility_maximizer.py index 939a6f80e..980add289 100644 --- a/tests/test_decision_making/test_acquisition_maximizer.py +++ b/tests/test_decision_making/test_utility_maximizer.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from jax.config import config +from jax import config config.update("jax_enable_x64", True) @@ -20,23 +20,23 @@ import jax.random as jr import pytest -from gpjax.decision_making.acquisition_maximizer import ( - AbstractAcquisitionMaximizer, - ContinuousAcquisitionMaximizer, - _get_discrete_maximizer, -) from gpjax.decision_making.test_functions.continuous_functions import ( AbstractContinuousTestFunction, Forrester, LogarithmicGoldsteinPrice, Quadratic, ) +from gpjax.decision_making.utility_maximizer import ( + AbstractUtilityMaximizer, + ContinuousUtilityMaximizer, + _get_discrete_maximizer, +) from gpjax.typing import KeyArray -def test_abstract_acquisition_maximizer(): +def test_abstract_utility_maximizer(): with pytest.raises(TypeError): - AbstractAcquisitionMaximizer() + AbstractUtilityMaximizer() @pytest.mark.parametrize( @@ -53,13 +53,13 @@ def test_discrete_maximizer_returns_correct_point( key: KeyArray, ): query_points = test_function.generate_test_points(1000, key=key) - acquisition_function = lambda x: -1.0 * test_function.evaluate(x) - acquisition_vals = acquisition_function(query_points) - true_max_acquisition_val = jnp.max(acquisition_vals) - discrete_maximizer = _get_discrete_maximizer(query_points, acquisition_function) + utility_function = lambda x: -1.0 * test_function.evaluate(x) + utility_vals = utility_function(query_points) + true_max_utility_val = jnp.max(utility_vals) + discrete_maximizer = _get_discrete_maximizer(query_points, utility_function) assert discrete_maximizer.shape == (1, dimensionality) assert discrete_maximizer.dtype == jnp.float64 - assert acquisition_function(discrete_maximizer)[0][0] == true_max_acquisition_val + assert utility_function(discrete_maximizer)[0][0] == true_max_utility_val @pytest.mark.parametrize("num_initial_samples", [0, -1, -10]) @@ -67,7 +67,7 @@ def test_continuous_maximizer_raises_error_with_erroneous_num_initial_samples( num_initial_samples: int, ): with pytest.raises(ValueError): - ContinuousAcquisitionMaximizer( + ContinuousUtilityMaximizer( num_initial_samples=num_initial_samples, num_restarts=1 ) @@ -77,7 +77,7 @@ def test_continuous_maximizer_raises_error_with_erroneous_num_restarts( num_restarts: int, ): with pytest.raises(ValueError): - ContinuousAcquisitionMaximizer(num_initial_samples=1, num_restarts=num_restarts) + ContinuousUtilityMaximizer(num_initial_samples=1, num_restarts=num_restarts) @pytest.mark.parametrize( @@ -95,20 +95,20 @@ def test_continous_maximizer_returns_same_point_with_same_key( key: KeyArray, num_restarts: int, ): - continuous_maximizer_one = ContinuousAcquisitionMaximizer( + continuous_maximizer_one = ContinuousUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) - continuous_maximizer_two = ContinuousAcquisitionMaximizer( + continuous_maximizer_two = ContinuousUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) - acquisition_function = lambda x: -1.0 * test_function.evaluate(x) + utility_function = lambda x: -1.0 * test_function.evaluate(x) maximizer_one = continuous_maximizer_one.maximize( - acquisition_function=acquisition_function, + utility_function=utility_function, search_space=test_function.search_space, key=key, ) maximizer_two = continuous_maximizer_two.maximize( - acquisition_function=acquisition_function, + utility_function=utility_function, search_space=test_function.search_space, key=key, ) @@ -137,19 +137,19 @@ def test_continuous_maximizer_finds_correct_point( key: KeyArray, num_restarts: int, ): - continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( + continuous_utility_maximizer = ContinuousUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) - acquisition_function = lambda x: -1.0 * test_function.evaluate(x) - true_acquisition_maximizer = test_function.minimizer - maximizer = continuous_acquisition_maximizer.maximize( - acquisition_function=acquisition_function, + utility_function = lambda x: -1.0 * test_function.evaluate(x) + true_utility_maximizer = test_function.minimizer + maximizer = continuous_utility_maximizer.maximize( + utility_function=utility_function, search_space=test_function.search_space, key=key, ) assert maximizer.shape == (1, dimensionality) assert maximizer.dtype == jnp.float64 - assert jnp.allclose(maximizer, true_acquisition_maximizer, atol=1e-6).all() + assert jnp.allclose(maximizer, true_utility_maximizer, atol=1e-6).all() @pytest.mark.parametrize("key", [jr.PRNGKey(42), jr.PRNGKey(10), jr.PRNGKey(1)]) @@ -159,17 +159,17 @@ def test_continuous_maximizer_finds_correct_point( ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_continuous_maximizer_jaxopt_component(key: KeyArray, num_restarts: int): quadratic = Quadratic() - continuous_acquisition_maximizer = ContinuousAcquisitionMaximizer( + continuous_utility_maximizer = ContinuousUtilityMaximizer( num_initial_samples=1, # Force JaxOpt L-GFBS-B to do the heavy lifting num_restarts=num_restarts, ) - acquisition_function = lambda x: -1.0 * quadratic.evaluate(x) - true_acquisition_maximizer = quadratic.minimizer - maximizer = continuous_acquisition_maximizer.maximize( - acquisition_function=acquisition_function, + utility_function = lambda x: -1.0 * quadratic.evaluate(x) + true_utility_maximizer = quadratic.minimizer + maximizer = continuous_utility_maximizer.maximize( + utility_function=utility_function, search_space=quadratic.search_space, key=key, ) assert maximizer.shape == (1, 1) assert maximizer.dtype == jnp.float64 - assert jnp.allclose(maximizer, true_acquisition_maximizer, atol=1e-6).all() + assert jnp.allclose(maximizer, true_utility_maximizer, atol=1e-6).all() diff --git a/tests/test_decision_making/utils.py b/tests/test_decision_making/utils.py index f92b793d8..90ad2d75a 100644 --- a/tests/test_decision_making/utils.py +++ b/tests/test_decision_making/utils.py @@ -16,30 +16,30 @@ from beartype.typing import Mapping from gpjax.dataset import Dataset -from gpjax.decision_making.acquisition_functions import ( - AbstractAcquisitionFunctionBuilder, - AcquisitionFunction, -) from gpjax.decision_making.test_functions import Quadratic +from gpjax.decision_making.utility_functions import ( + AbstractUtilityFunctionBuilder, + UtilityFunction, +) from gpjax.gps import ConjugatePosterior from gpjax.typing import KeyArray -class QuadraticAcquisitionFunctionBuilder(AbstractAcquisitionFunctionBuilder): +class QuadraticUtilityFunctionBuilder(AbstractUtilityFunctionBuilder): """ - Dummy acquisition function builder for testing purposes, which returns the negative + Dummy utility function builder for testing purposes, which returns the negative of the value of a quadratic test function at the input points. This is because - acquisition functions are *maximised*, and we wish to *minimise* the quadratic test + utility functions are *maximised*, and we wish to *minimise* the quadratic test function. """ - def build_acquisition_function( + def build_utility_function( self, posteriors: Mapping[str, ConjugatePosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> AcquisitionFunction: + ) -> UtilityFunction: test_function = Quadratic() return lambda x: -1.0 * test_function.evaluate( x - ) # Acquisition functions are *maximised* + ) # Utility functions are *maximised* From 57d352ad753d78a0dad879cbfa0fff164cdad279 Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Tue, 5 Sep 2023 17:26:03 +0100 Subject: [PATCH 54/76] moved data to static branch, qol changes across notebook --- docs/examples/data/gulfdata_test.csv | 545 -------------------------- docs/examples/data/gulfdata_train.csv | 21 - docs/examples/oceanmodelling.py | 229 ++++++----- 3 files changed, 112 insertions(+), 683 deletions(-) delete mode 100644 docs/examples/data/gulfdata_test.csv delete mode 100644 docs/examples/data/gulfdata_train.csv diff --git a/docs/examples/data/gulfdata_test.csv b/docs/examples/data/gulfdata_test.csv deleted file mode 100644 index 6d2517826..000000000 --- a/docs/examples/data/gulfdata_test.csv +++ /dev/null @@ -1,545 +0,0 @@ -,lon,lat,ubar,vbar,shape -0,-90.78823529,24.03125,0.012934734,-0.119138002,34 -1,-90.57647059,24.03125,-0.048447536,-0.053945304,16 -2,-90.36470588,24.03125,-0.063418192,0.009081421,0 -3,-90.15294118,24.03125,-0.079781553,-0.052787458,0 -4,-89.94117647,24.03125,-0.037646996,-0.067648494,0 -5,-89.72941176,24.03125,-0.013759543,-0.050209018,0 -6,-89.51764706,24.03125,-0.056024482,-0.07421219,0 -7,-89.30588235,24.03125,-0.040638775,-0.07613701,0 -8,-89.09411765,24.03125,-0.050733638,-0.015584665,0 -9,-88.88235294,24.03125,-0.029212873,-0.036183464,0 -10,-88.67058824,24.03125,-0.037372362,-0.156029259,0 -11,-88.45882353,24.03125,-0.01494416,-0.06919967,0 -12,-88.24705882,24.03125,-0.062871325,-0.012938229,0 -13,-88.03529412,24.03125,-0.109551896,0.018954081,0 -14,-87.82352941,24.03125,-0.269340276,-0.074616515,0 -15,-87.61176471,24.03125,-0.313617175,0.114040312,0 -16,-87.4,24.03125,-0.467162405,0.301118178,0 -17,-87.18823529,24.03125,-0.438090893,0.288097941,0 -18,-86.97647059,24.03125,-0.295175025,0.398262865,0 -19,-86.76470588,24.03125,-0.07773377,0.026426916,0 -20,-86.55294118,24.03125,-0.049904935,-0.013369981,0 -21,-86.34117647,24.03125,-0.010054117,-0.015447627,0 -22,-86.12941176,24.03125,-0.059930947,0.060322613,0 -23,-85.91764706,24.03125,-0.079267656,-0.027754038,0 -24,-85.70588235,24.03125,-0.001990859,-0.030039107,0 -25,-85.49411765,24.03125,0.139947451,-0.097313427,0 -26,-85.28235294,24.03125,0.203027776,-0.034414591,0 -27,-85.07058824,24.03125,0.18490045,-0.180825723,0 -28,-84.85882353,24.03125,0.259426357,-0.255191914,0 -29,-84.64705882,24.03125,0.403989777,-0.344969787,0 -30,-84.43529412,24.03125,0.418881952,-0.306396519,0 -31,-84.22352941,24.03125,0.401640041,-0.279468744,0 -32,-84.01176471,24.03125,0.405423791,-0.281736808,0 -33,-83.8,24.03125,0.300436065,-0.25017157,0 -34,-90.78823529,24.2625,-0.001970387,-0.048574076,0 -35,-90.57647059,24.2625,-0.012415587,-0.036935943,0 -36,-90.36470588,24.2625,0.003214217,-0.059640195,0 -37,-90.15294118,24.2625,0.048173025,-0.040376054,0 -38,-89.94117647,24.2625,0.021711527,-0.060253566,0 -39,-89.72941176,24.2625,0.014017724,-0.087975435,0 -40,-89.51764706,24.2625,0.111103018,-0.099072446,0 -41,-89.30588235,24.2625,0.063349561,-0.10544855,0 -42,-89.09411765,24.2625,0.080851702,-0.053605717,0 -43,-88.88235294,24.2625,0.17987771,-0.187315712,0 -44,-88.67058824,24.2625,0.148566514,-0.202426321,0 -45,-88.45882353,24.2625,0.076863273,0.00234853,0 -46,-88.24705882,24.2625,0.033361642,0.043027404,0 -47,-88.03529412,24.2625,-0.094032501,0.092244477,0 -48,-87.82352941,24.2625,-0.352788048,0.222832158,0 -49,-87.61176471,24.2625,-0.527584387,0.319983483,0 -50,-87.4,24.2625,-0.31815162,0.075536871,0 -51,-87.18823529,24.2625,-0.378981038,0.080490224,0 -52,-86.97647059,24.2625,-0.230711752,0.081317482,0 -53,-86.76470588,24.2625,-0.073356462,-0.038011937,0 -54,-86.55294118,24.2625,-0.055855093,-0.028346203,0 -55,-86.34117647,24.2625,-0.13545188,0.086092559,0 -56,-86.12941176,24.2625,-0.048275949,0.03036671,0 -57,-85.91764706,24.2625,-0.031056324,0.000444703,0 -58,-85.70588235,24.2625,-0.097879193,-0.15157636,0 -59,-85.49411765,24.2625,-0.032475112,-0.265242133,0 -60,-85.28235294,24.2625,0.086591979,-0.134721176,0 -61,-85.07058824,24.2625,0.129215449,-0.151881538,0 -62,-84.85882353,24.2625,0.215008841,-0.277468569,0 -63,-84.64705882,24.2625,0.346628287,-0.392841735,0 -64,-84.43529412,24.2625,0.261683327,-0.234586921,0 -65,-84.22352941,24.2625,0.220448207,-0.252728914,0 -66,-84.01176471,24.2625,0.289019892,-0.223931847,0 -67,-83.8,24.2625,0.221771131,-0.209547007,0 -68,-90.78823529,24.49375,-0.107406962,-0.049236746,0 -69,-90.57647059,24.49375,-0.073294697,-0.088041875,0 -70,-90.36470588,24.49375,-0.032563777,-0.076576075,0 -71,-90.15294118,24.49375,-0.029756774,-0.100970247,0 -72,-89.94117647,24.49375,0.00864684,-0.074296756,0 -73,-89.72941176,24.49375,0.057434301,-0.165396174,0 -74,-89.51764706,24.49375,0.082839096,-0.11400015,0 -75,-89.30588235,24.49375,0.289836275,-0.217025145,0 -76,-89.09411765,24.49375,0.369932663,-0.201184574,0 -77,-88.88235294,24.49375,0.336533257,-0.190465581,0 -78,-88.67058824,24.49375,0.133076887,0.023502245,0 -79,-88.45882353,24.49375,0.092060005,0.053315308,0 -80,-88.24705882,24.49375,0.035149461,0.116643541,0 -81,-88.03529412,24.49375,-0.045901414,0.225121066,0 -82,-87.82352941,24.49375,-0.299234418,0.349037405,0 -83,-87.61176471,24.49375,-0.445357905,0.464884889,0 -84,-87.4,24.49375,-0.246941376,0.130840473,0 -85,-87.18823529,24.49375,-0.322251609,0.108879502,0 -86,-86.97647059,24.49375,-0.221729518,-0.142641746,0 -87,-86.76470588,24.49375,-0.180857265,-0.073733515,0 -88,-86.55294118,24.49375,-0.29547835,0.077388131,0 -89,-86.34117647,24.49375,-0.262170615,-0.03014991,0 -90,-86.12941176,24.49375,-0.195716753,0.016608455,0 -91,-85.91764706,24.49375,-0.049866945,-0.024089298,0 -92,-85.70588235,24.49375,-0.018318565,-0.165395019,0 -93,-85.49411765,24.49375,0.015679874,-0.192181915,0 -94,-85.28235294,24.49375,-0.03550123,-0.236503143,0 -95,-85.07058824,24.49375,0.080393272,-0.106866696,0 -96,-84.85882353,24.49375,0.067912807,-0.28282864,0 -97,-84.64705882,24.49375,0.199518282,-0.407025005,0 -98,-84.43529412,24.49375,0.193570146,-0.137194872,0 -99,-84.22352941,24.49375,0.157749543,-0.186695753,0 -100,-84.01176471,24.49375,0.187017952,-0.288034057,0 -101,-83.8,24.49375,0.180010234,-0.145048261,0 -102,-90.78823529,24.725,-0.001920843,-0.057100952,0 -103,-90.57647059,24.725,-0.005202058,-0.062615868,0 -104,-90.36470588,24.725,-0.018122687,-0.160703595,0 -105,-90.15294118,24.725,0.022168602,-0.147095471,0 -106,-89.94117647,24.725,0.098186242,-0.200168604,0 -107,-89.72941176,24.725,0.114127181,-0.257008367,0 -108,-89.51764706,24.725,0.288965519,-0.24562694,0 -109,-89.30588235,24.725,0.366871235,-0.310349972,0 -110,-89.09411765,24.725,0.316964648,-0.167555442,0 -111,-88.88235294,24.725,0.093938286,0.099809033,0 -112,-88.67058824,24.725,0.032558011,0.124588301,0 -113,-88.45882353,24.725,-0.045144374,0.164408293,0 -114,-88.24705882,24.725,-0.104119643,0.238643039,0 -115,-88.03529412,24.725,-0.159232622,0.2970519,0 -116,-87.82352941,24.725,-0.481320719,0.591122739,0 -117,-87.61176471,24.725,-0.210899216,0.164175907,0 -118,-87.4,24.725,-0.29225526,0.200847558,0 -119,-87.18823529,24.725,-0.253726305,0.159467611,0 -120,-86.97647059,24.725,-0.234049572,-0.061609694,0 -121,-86.76470588,24.725,-0.355413504,-0.13213955,0 -122,-86.55294118,24.725,-0.32187465,-0.093146523,0 -123,-86.34117647,24.725,-0.144105695,-0.117690733,0 -124,-86.12941176,24.725,-0.0199346,-0.067486114,0 -125,-85.91764706,24.725,-0.037872691,-0.187187884,0 -126,-85.70588235,24.725,0.010437814,-0.17594918,0 -127,-85.49411765,24.725,0.052576319,-0.252479388,0 -128,-85.28235294,24.725,0.042249791,-0.283942508,0 -129,-85.07058824,24.725,0.004013188,-0.289127388,0 -130,-84.85882353,24.725,0.048345871,-0.309461433,0 -131,-84.64705882,24.725,0.097446268,-0.455497697,0 -132,-84.43529412,24.725,0.091244058,-0.164644918,0 -133,-84.22352941,24.725,0.137958525,-0.194290947,0 -134,-84.01176471,24.725,0.11270575,-0.214570236,0 -135,-83.8,24.725,0.04446445,-0.065173442,0 -136,-90.78823529,24.95625,-0.068671315,-0.070961189,0 -137,-90.57647059,24.95625,-0.062771404,-0.093159722,0 -138,-90.36470588,24.95625,-0.007674697,-0.203497023,0 -139,-90.15294118,24.95625,0.0270646,-0.123043403,0 -140,-89.94117647,24.95625,-0.001125839,-0.159442335,0 -141,-89.72941176,24.95625,0.155152339,-0.299351029,0 -142,-89.51764706,24.95625,0.20747634,-0.338449702,0 -143,-89.30588235,24.95625,0.127189226,-0.203436091,0 -144,-89.09411765,24.95625,-0.002304782,0.009427787,0 -145,-88.88235294,24.95625,-0.021486956,0.197988496,0 -146,-88.67058824,24.95625,-0.065733465,0.212740665,0 -147,-88.45882353,24.95625,-0.114057704,0.21722011,0 -148,-88.24705882,24.95625,-0.155708378,0.268737791,0 -149,-88.03529412,24.95625,-0.080807704,0.231927877,0 -150,-87.82352941,24.95625,-0.147157954,0.291938004,0 -151,-87.61176471,24.95625,-0.212221319,0.222802073,0 -152,-87.4,24.95625,-0.227550983,0.286225784,0 -153,-87.18823529,24.95625,-0.283724468,0.181675988,0 -154,-86.97647059,24.95625,-0.110271126,-0.078571338,0 -155,-86.76470588,24.95625,-0.182219119,-0.213026957,0 -156,-86.55294118,24.95625,-0.191750055,-0.230042074,0 -157,-86.34117647,24.95625,-0.21463129,-0.176883138,0 -158,-86.12941176,24.95625,-0.107571021,-0.15642493,0 -159,-85.91764706,24.95625,0.012545381,-0.216788815,0 -160,-85.70588235,24.95625,0.081749417,-0.278183667,0 -161,-85.49411765,24.95625,0.028316619,-0.289940992,0 -162,-85.28235294,24.95625,0.053155096,-0.290313879,0 -163,-85.07058824,24.95625,-0.006158111,-0.232317753,0 -164,-84.85882353,24.95625,0.030940432,-0.367238532,0 -165,-84.64705882,24.95625,-0.015491593,-0.295685535,0 -166,-84.43529412,24.95625,0.011379354,-0.238575767,0 -167,-84.22352941,24.95625,0.055387965,-0.274255734,0 -168,-84.01176471,24.95625,0.05214515,-0.117859951,0 -169,-83.8,24.95625,-0.0080579,-0.011900092,0 -170,-90.78823529,25.1875,-0.12432471,-0.117731685,0 -171,-90.57647059,25.1875,-0.174591484,-0.131972206,0 -172,-90.36470588,25.1875,-0.144562862,-0.312662359,0 -173,-90.15294118,25.1875,-0.071969315,-0.206957357,0 -174,-89.94117647,25.1875,-0.073665569,-0.186713773,0 -175,-89.72941176,25.1875,-0.131147151,-0.448172793,0 -176,-89.51764706,25.1875,0.018620377,-0.331644793,0 -177,-89.30588235,25.1875,0.009998903,-0.119112152,0 -178,-89.09411765,25.1875,-0.073074476,0.054603658,0 -179,-88.88235294,25.1875,-0.105464374,0.157114053,0 -180,-88.67058824,25.1875,-0.080341096,0.285757799,0 -181,-88.45882353,25.1875,-0.082986553,0.306411888,0 -182,-88.24705882,25.1875,-0.104068303,0.275476961,0 -183,-88.03529412,25.1875,-0.052277643,0.180606565,0 -184,-87.82352941,25.1875,-0.102496127,0.265649837,0 -185,-87.61176471,25.1875,-0.114445904,0.407122675,0 -186,-87.4,25.1875,-0.111313983,0.264506462,0 -187,-87.18823529,25.1875,-0.05183303,0.080687298,0 -188,-86.97647059,25.1875,-0.039709437,-0.123221653,0 -189,-86.76470588,25.1875,-0.031455607,-0.117034118,0 -190,-86.55294118,25.1875,-0.072164475,-0.061583073,0 -191,-86.34117647,25.1875,-0.134109372,-0.185987084,0 -192,-86.12941176,25.1875,-0.144734126,-0.261783824,0 -193,-85.91764706,25.1875,-0.035302626,-0.297357451,0 -194,-85.70588235,25.1875,0.082609131,-0.320545628,0 -195,-85.49411765,25.1875,0.03083069,-0.212149475,0 -196,-85.28235294,25.1875,0.000866022,-0.252272292,0 -197,-85.07058824,25.1875,0.071537092,-0.344332424,0 -198,-84.85882353,25.1875,0.03155944,-0.399977404,0 -199,-84.64705882,25.1875,0.08220279,-0.368149906,0 -200,-84.43529412,25.1875,-0.032850763,-0.236765644,0 -201,-84.22352941,25.1875,-0.048986644,-0.25707726,0 -202,-84.01176471,25.1875,-0.059588521,-0.090060442,0 -203,-83.8,25.1875,-0.057199879,-0.049451263,0 -204,-90.78823529,25.41875,-0.132358362,-0.087289275,0 -205,-90.57647059,25.41875,-0.202081522,-0.125632991,0 -206,-90.36470588,25.41875,-0.216905583,-0.212145558,0 -207,-90.15294118,25.41875,-0.165846871,-0.232816711,0 -208,-89.94117647,25.41875,-0.136376108,-0.256474579,0 -209,-89.72941176,25.41875,-0.143006764,-0.471258778,0 -210,-89.51764706,25.41875,-0.116104577,-0.44676606,0 -211,-89.30588235,25.41875,-0.05307556,-0.065772887,0 -212,-89.09411765,25.41875,-0.063669139,0.124027217,0 -213,-88.88235294,25.41875,-0.100326703,0.186230618,0 -214,-88.67058824,25.41875,-0.086277437,0.272444831,0 -215,-88.45882353,25.41875,0.006588612,0.248742571,0 -216,-88.24705882,25.41875,0.036745925,0.262806039,0 -217,-88.03529412,25.41875,-0.000240312,0.20942527,0 -218,-87.82352941,25.41875,0.108715689,0.211728295,0 -219,-87.61176471,25.41875,0.040306395,0.346730418,0 -220,-87.4,25.41875,0.021907225,0.373667956,0 -221,-87.18823529,25.41875,0.096129114,-0.012310808,0 -222,-86.97647059,25.41875,0.058595472,-0.083412856,0 -223,-86.76470588,25.41875,0.147405198,-0.087404083,0 -224,-86.55294118,25.41875,0.124921196,-0.114008829,0 -225,-86.34117647,25.41875,0.069967211,-0.162582809,0 -226,-86.12941176,25.41875,0.205385343,-0.258467212,0 -227,-85.91764706,25.41875,0.033662121,-0.279081569,0 -228,-85.70588235,25.41875,-0.098726156,-0.350882919,0 -229,-85.49411765,25.41875,0.018397882,-0.277828386,0 -230,-85.28235294,25.41875,0.077132458,-0.335538009,0 -231,-85.07058824,25.41875,0.046162657,-0.467845926,0 -232,-84.85882353,25.41875,0.017603575,-0.383941281,0 -233,-84.64705882,25.41875,-0.039346258,-0.285323483,0 -234,-84.43529412,25.41875,-0.019037244,-0.239963698,0 -235,-84.22352941,25.41875,-0.054063007,-0.195310247,0 -236,-84.01176471,25.41875,-0.065863705,-0.093853611,0 -237,-83.8,25.41875,-0.054659494,-0.04142678,0 -238,-90.78823529,25.65,-0.261424878,-0.105294813,0 -239,-90.57647059,25.65,-0.21708168,-0.067574425,0 -240,-90.36470588,25.65,-0.1705854,-0.121787582,0 -241,-90.15294118,25.65,-0.21769884,-0.244759145,0 -242,-89.94117647,25.65,-0.221300657,-0.285468652,0 -243,-89.72941176,25.65,-0.143047053,-0.278902819,0 -244,-89.51764706,25.65,-0.154745376,-0.558645986,0 -245,-89.30588235,25.65,-0.066653394,-0.186500112,0 -246,-89.09411765,25.65,-0.058375747,0.099949004,0 -247,-88.88235294,25.65,-0.023507122,0.158206945,0 -248,-88.67058824,25.65,-0.044026717,0.189984867,0 -249,-88.45882353,25.65,-0.021099937,0.324524058,0 -250,-88.24705882,25.65,0.003162908,0.252266646,0 -251,-88.03529412,25.65,0.076919374,0.286853648,0 -252,-87.82352941,25.65,0.059418464,0.142062396,0 -253,-87.61176471,25.65,0.153557224,0.337575841,0 -254,-87.4,25.65,0.210838451,0.374218887,0 -255,-87.18823529,25.65,0.119040151,-0.05485577,0 -256,-86.97647059,25.65,0.124045522,-0.088413895,0 -257,-86.76470588,25.65,0.160107748,-0.082785734,0 -258,-86.55294118,25.65,0.216409423,-0.067934909,0 -259,-86.34117647,25.65,0.200635283,-0.120532465,0 -260,-86.12941176,25.65,0.250672376,-0.163575534,0 -261,-85.91764706,25.65,0.274983119,-0.115574241,0 -262,-85.70588235,25.65,0.353606617,-0.191219611,0 -263,-85.49411765,25.65,0.147884159,-0.345352765,0 -264,-85.28235294,25.65,0.142828267,-0.254648914,0 -265,-85.07058824,25.65,0.149878332,-0.386357103,0 -266,-84.85882353,25.65,0.079479562,-0.3218503,0 -267,-84.64705882,25.65,-0.039876229,-0.322739291,0 -268,-84.43529412,25.65,-0.020601203,-0.258910138,0 -269,-84.22352941,25.65,-0.030342452,-0.141943145,0 -270,-84.01176471,25.65,-0.026403279,-0.116659437,0 -271,-83.8,25.65,-0.028221576,-0.062310204,0 -272,-90.78823529,25.88125,-0.124851721,-0.128636466,0 -273,-90.57647059,25.88125,-0.168870093,-0.08999443,0 -274,-90.36470588,25.88125,-0.17231575,-0.165715883,0 -275,-90.15294118,25.88125,-0.152776566,-0.200739554,0 -276,-89.94117647,25.88125,-0.176438638,-0.24819344,0 -277,-89.72941176,25.88125,-0.133104814,-0.33179839,0 -278,-89.51764706,25.88125,-0.150245786,-0.546541834,0 -279,-89.30588235,25.88125,-0.037534689,-0.220120979,0 -280,-89.09411765,25.88125,-0.002611095,0.057836286,0 -281,-88.88235294,25.88125,0.02291235,0.168404335,0 -282,-88.67058824,25.88125,0.078929694,0.09678654,0 -283,-88.45882353,25.88125,0.146978722,0.152686076,0 -284,-88.24705882,25.88125,0.141612505,0.233362174,0 -285,-88.03529412,25.88125,0.16915561,0.208814065,0 -286,-87.82352941,25.88125,0.091689657,0.119051302,0 -287,-87.61176471,25.88125,0.146638228,0.155958491,0 -288,-87.4,25.88125,0.217603321,0.494927174,0 -289,-87.18823529,25.88125,0.23878443,-0.123333879,0 -290,-86.97647059,25.88125,0.194784911,-0.224739369,0 -291,-86.76470588,25.88125,0.251980448,-0.142474432,0 -292,-86.55294118,25.88125,0.391586736,-0.146894892,0 -293,-86.34117647,25.88125,0.407873416,-0.167468809,0 -294,-86.12941176,25.88125,0.468474617,-0.037905129,0 -295,-85.91764706,25.88125,0.449674371,-0.06903519,0 -296,-85.70588235,25.88125,0.360212995,-0.04202529,0 -297,-85.49411765,25.88125,0.268270971,-0.060195988,0 -298,-85.28235294,25.88125,0.13894377,-0.215928251,0 -299,-85.07058824,25.88125,0.084320653,-0.296736669,0 -300,-84.85882353,25.88125,0.116764238,-0.280460219,0 -301,-84.64705882,25.88125,0.013730035,-0.218459536,0 -302,-84.43529412,25.88125,-0.050889981,-0.105587868,0 -303,-84.22352941,25.88125,-0.019300266,-0.211886994,0 -304,-84.01176471,25.88125,0.019427973,-0.101704304,0 -305,-83.8,25.88125,0.031684577,-0.050969537,0 -306,-90.78823529,26.1125,0.039749266,-0.105871709,0 -307,-90.57647059,26.1125,0.010327879,-0.025544931,0 -308,-90.36470588,26.1125,-0.050688536,-0.127234109,0 -309,-90.15294118,26.1125,-0.092401096,-0.111699661,0 -310,-89.94117647,26.1125,-0.127450769,-0.234260364,0 -311,-89.72941176,26.1125,-0.093266615,-0.323968501,0 -312,-89.51764706,26.1125,-0.026599236,-0.509762616,0 -313,-89.30588235,26.1125,-0.005263159,-0.328953197,0 -314,-89.09411765,26.1125,0.052395798,0.013019942,0 -315,-88.88235294,26.1125,0.130517568,0.013353112,0 -316,-88.67058824,26.1125,0.141025843,0.143783343,0 -317,-88.45882353,26.1125,0.129038512,0.139305276,0 -318,-88.24705882,26.1125,0.210648567,0.343530606,0 -319,-88.03529412,26.1125,0.31663453,0.25560511,0 -320,-87.82352941,26.1125,0.245415092,0.143963519,0 -321,-87.61176471,26.1125,0.249265433,0.137448724,0 -322,-87.4,26.1125,0.332134225,0.23410559,0 -323,-87.18823529,26.1125,0.252730968,-0.150856718,0 -324,-86.97647059,26.1125,0.273283347,-0.21380526,0 -325,-86.76470588,26.1125,0.361644223,-0.243457819,0 -326,-86.55294118,26.1125,0.327327028,-0.192158909,0 -327,-86.34117647,26.1125,0.254002908,-0.0821479,0 -328,-86.12941176,26.1125,0.253089475,-0.009968208,0 -329,-85.91764706,26.1125,0.375831016,-0.066147891,0 -330,-85.70588235,26.1125,0.350098008,0.021628024,0 -331,-85.49411765,26.1125,0.330705502,-0.06842824,0 -332,-85.28235294,26.1125,0.187556477,0.035588136,0 -333,-85.07058824,26.1125,0.13715475,-0.180254345,0 -334,-84.85882353,26.1125,0.075806249,-0.127921871,0 -335,-84.64705882,26.1125,0.046370205,-0.118958648,0 -336,-84.43529412,26.1125,0.043288109,-0.254594504,0 -337,-84.22352941,26.1125,0.09574632,-0.30158871,0 -338,-84.01176471,26.1125,0.016568306,-0.107781119,0 -339,-83.8,26.1125,0.008828996,-0.091147237,0 -340,-90.78823529,26.34375,0.063502918,-0.116123223,0 -341,-90.57647059,26.34375,0.064182845,-0.024932155,0 -342,-90.36470588,26.34375,-0.016636174,-0.057556913,0 -343,-90.15294118,26.34375,-0.040705093,-0.113203941,0 -344,-89.94117647,26.34375,-0.01642502,-0.178565097,0 -345,-89.72941176,26.34375,-0.046116475,-0.328245069,0 -346,-89.51764706,26.34375,0.01373015,-0.435091742,0 -347,-89.30588235,26.34375,0.017788923,-0.225388643,0 -348,-89.09411765,26.34375,0.116123321,-0.010683381,0 -349,-88.88235294,26.34375,0.166419287,-0.049395028,0 -350,-88.67058824,26.34375,0.140347119,0.154749278,0 -351,-88.45882353,26.34375,0.196117444,0.098690536,0 -352,-88.24705882,26.34375,0.232865254,0.172522437,0 -353,-88.03529412,26.34375,0.382617258,0.207050693,0 -354,-87.82352941,26.34375,0.387904055,-0.089413643,0 -355,-87.61176471,26.34375,0.587562426,0.082745047,0 -356,-87.4,26.34375,0.487439097,0.09192189,0 -357,-87.18823529,26.34375,0.395320311,-0.07489581,0 -358,-86.97647059,26.34375,0.382626703,-0.207695305,0 -359,-86.76470588,26.34375,0.316409035,-0.114660594,0 -360,-86.55294118,26.34375,0.286911566,-0.100115912,0 -361,-86.34117647,26.34375,0.290432768,0.004263782,0 -362,-86.12941176,26.34375,0.379395858,0.024734445,0 -363,-85.91764706,26.34375,0.414484216,-0.077757217,0 -364,-85.70588235,26.34375,0.396400936,-0.052666671,0 -365,-85.49411765,26.34375,0.231168763,0.058377972,0 -366,-85.28235294,26.34375,0.083878426,0.071419445,0 -367,-85.07058824,26.34375,0.098906978,-0.06855577,0 -368,-84.85882353,26.34375,0.091478539,-0.111025639,0 -369,-84.64705882,26.34375,0.137048478,-0.183682377,0 -370,-84.43529412,26.34375,0.132850414,-0.222123323,0 -371,-84.22352941,26.34375,0.06581992,-0.16019666,0 -372,-84.01176471,26.34375,0.02986959,-0.094100613,0 -373,-83.8,26.34375,0.010203849,-0.063765137,0 -374,-90.78823529,26.575,0.114100825,-0.140868671,0 -375,-90.57647059,26.575,0.001893497,0.001049587,0 -376,-90.36470588,26.575,0.010214141,0.025098048,0 -377,-90.15294118,26.575,-0.045356443,-0.050229912,0 -378,-89.94117647,26.575,-0.083959465,-0.156061962,0 -379,-89.72941176,26.575,-0.075323043,-0.201721416,0 -380,-89.51764706,26.575,-0.140282147,-0.453087671,0 -381,-89.30588235,26.575,-0.079538885,-0.404974743,0 -382,-89.09411765,26.575,-0.007734609,-0.133299686,0 -383,-88.88235294,26.575,0.099508798,-0.001144728,0 -384,-88.67058824,26.575,0.173997699,0.130031045,0 -385,-88.45882353,26.575,0.141594529,0.144096641,0 -386,-88.24705882,26.575,0.141362382,0.145186239,0 -387,-88.03529412,26.575,0.23624143,-0.23097345,0 -388,-87.82352941,26.575,0.407392559,-0.25638763,0 -389,-87.61176471,26.575,0.444457146,-0.043794848,0 -390,-87.4,26.575,0.421860633,0.022664385,0 -391,-87.18823529,26.575,0.252514958,-0.076932475,0 -392,-86.97647059,26.575,0.269705859,0.008269503,0 -393,-86.76470588,26.575,0.263946814,-0.020907239,0 -394,-86.55294118,26.575,0.217665932,-0.014619679,0 -395,-86.34117647,26.575,0.231209801,-0.038629444,0 -396,-86.12941176,26.575,0.277662711,-0.059881691,0 -397,-85.91764706,26.575,0.391977347,-0.073687741,0 -398,-85.70588235,26.575,0.193642149,0.09105973,0 -399,-85.49411765,26.575,0.135910253,0.150897976,0 -400,-85.28235294,26.575,0.081446953,0.103790713,0 -401,-85.07058824,26.575,0.165006513,-0.121109339,0 -402,-84.85882353,26.575,0.163791573,-0.071855205,0 -403,-84.64705882,26.575,0.216144717,-0.114085579,0 -404,-84.43529412,26.575,0.083768764,-0.156322818,0 -405,-84.22352941,26.575,0.067137785,-0.125229948,0 -406,-84.01176471,26.575,0.06205672,-0.05864353,0 -407,-83.8,26.575,0.048044397,-0.036289716,0 -408,-90.78823529,26.80625,-0.009206026,-0.050935001,0 -409,-90.57647059,26.80625,0.026055447,-0.010874153,0 -410,-90.36470588,26.80625,-0.001108608,0.036281546,0 -411,-90.15294118,26.80625,-0.001050662,0.00439152,0 -412,-89.94117647,26.80625,-0.037619473,-0.070344741,0 -413,-89.72941176,26.80625,-0.087097055,-0.129746668,0 -414,-89.51764706,26.80625,-0.082289091,-0.269996553,0 -415,-89.30588235,26.80625,-0.085363696,-0.500188584,0 -416,-89.09411765,26.80625,-0.018274711,-0.130577036,0 -417,-88.88235294,26.80625,-0.021421122,-0.0899137,0 -418,-88.67058824,26.80625,0.004297595,0.020707884,0 -419,-88.45882353,26.80625,0.071961736,0.10102665,0 -420,-88.24705882,26.80625,0.189715962,0.015628441,0 -421,-88.03529412,26.80625,0.313407203,-0.429966774,0 -422,-87.82352941,26.80625,0.20808154,-0.31952313,0 -423,-87.61176471,26.80625,0.252774688,-0.037492143,0 -424,-87.4,26.80625,0.147496585,0.058163017,0 -425,-87.18823529,26.80625,0.170121949,0.01569084,0 -426,-86.97647059,26.80625,0.272868114,0.003129819,0 -427,-86.76470588,26.80625,0.27851665,-0.03039473,0 -428,-86.55294118,26.80625,0.271119123,-0.091433736,0 -429,-86.34117647,26.80625,0.263479147,0.001308847,0 -430,-86.12941176,26.80625,0.189635515,0.001629487,0 -431,-85.91764706,26.80625,0.138263813,0.096907934,0 -432,-85.70588235,26.80625,0.050204287,0.151982655,0 -433,-85.49411765,26.80625,0.001833714,0.131963933,0 -434,-85.28235294,26.80625,0.017255819,0.053812478,0 -435,-85.07058824,26.80625,0.037496557,-0.044073832,0 -436,-84.85882353,26.80625,-0.007741361,-0.027330843,0 -437,-84.64705882,26.80625,0.052290738,-0.085001008,0 -438,-84.43529412,26.80625,0.070679854,-0.130382583,0 -439,-84.22352941,26.80625,0.044335471,-0.115202346,0 -440,-84.01176471,26.80625,0.023617886,-0.084583804,0 -441,-83.8,26.80625,0.014888157,-0.004931356,0 -442,-90.78823529,27.0375,0.119735596,-0.027908129,0 -443,-90.57647059,27.0375,0.019012357,-0.010418724,0 -444,-90.36470588,27.0375,0.005771756,0.042381814,0 -445,-90.15294118,27.0375,0.072508656,-0.020801246,0 -446,-89.94117647,27.0375,0.003529583,-0.024540724,0 -447,-89.72941176,27.0375,-0.014284738,-0.064779797,0 -448,-89.51764706,27.0375,-0.085726174,-0.162728182,0 -449,-89.30588235,27.0375,-0.163826484,-0.344525195,0 -450,-89.09411765,27.0375,-0.131306376,-0.196937123,0 -451,-88.88235294,27.0375,-0.054112787,-0.082520064,0 -452,-88.67058824,27.0375,-0.006738036,-0.048383266,0 -453,-88.45882353,27.0375,0.034884064,0.005350065,0 -454,-88.24705882,27.0375,0.122567068,-0.23259505,0 -455,-88.03529412,27.0375,0.175343144,-0.349672502,0 -456,-87.82352941,27.0375,0.031526809,-0.191488806,0 -457,-87.61176471,27.0375,0.042913317,-0.065327721,0 -458,-87.4,27.0375,0.039532322,0.03352164,0 -459,-87.18823529,27.0375,0.061265657,0.036573636,0 -460,-86.97647059,27.0375,0.11005837,-0.01610953,0 -461,-86.76470588,27.0375,0.170889344,-0.045335206,0 -462,-86.55294118,27.0375,0.148511835,-0.062515589,0 -463,-86.34117647,27.0375,0.045981978,-0.0291828,0 -464,-86.12941176,27.0375,-0.006363569,0.072645683,0 -465,-85.91764706,27.0375,-0.004755505,0.126540385,0 -466,-85.70588235,27.0375,-0.030352055,0.162635541,0 -467,-85.49411765,27.0375,-0.033442149,0.068033475,0 -468,-85.28235294,27.0375,0.013397289,0.01471379,0 -469,-85.07058824,27.0375,-0.011773853,-0.043954178,0 -470,-84.85882353,27.0375,0.008114761,-0.083275202,0 -471,-84.64705882,27.0375,0.02212113,-0.106110721,0 -472,-84.43529412,27.0375,0.064227691,-0.162982284,0 -473,-84.22352941,27.0375,0.040482379,-0.077476388,0 -474,-84.01176471,27.0375,0.011693432,-0.050369363,0 -475,-83.8,27.0375,-0.030124658,-0.012615871,0 -476,-90.78823529,27.26875,0.030676165,0.030950887,0 -477,-90.57647059,27.26875,0.034760864,0.023963734,0 -478,-90.36470588,27.26875,0.080762348,-0.048696228,0 -479,-90.15294118,27.26875,0.095401189,-0.028853933,0 -480,-89.94117647,27.26875,0.103311465,-0.006305736,0 -481,-89.72941176,27.26875,0.023110392,-0.045348843,0 -482,-89.51764706,27.26875,-0.033797614,-0.117178948,0 -483,-89.30588235,27.26875,-0.159231807,-0.228988806,0 -484,-89.09411765,27.26875,-0.173692256,-0.30389746,0 -485,-88.88235294,27.26875,-0.08350019,-0.104022606,0 -486,-88.67058824,27.26875,-0.022797293,-0.100029245,0 -487,-88.45882353,27.26875,0.157769672,-0.129609877,0 -488,-88.24705882,27.26875,0.304537401,-0.263900284,0 -489,-88.03529412,27.26875,0.149645451,-0.173959182,0 -490,-87.82352941,27.26875,0.049181865,-0.100372279,0 -491,-87.61176471,27.26875,-0.00291244,-0.059133449,0 -492,-87.4,27.26875,-0.027489384,0.015601954,0 -493,-87.18823529,27.26875,0.010687838,0.025344381,0 -494,-86.97647059,27.26875,0.034256483,-0.020263794,0 -495,-86.76470588,27.26875,0.037501277,-0.064002724,0 -496,-86.55294118,27.26875,0.019713713,0.003952043,0 -497,-86.34117647,27.26875,-0.037105206,0.057188768,0 -498,-86.12941176,27.26875,-0.085127285,0.095261856,0 -499,-85.91764706,27.26875,-0.094035817,0.112604394,0 -500,-85.70588235,27.26875,-0.07303864,0.108054833,0 -501,-85.49411765,27.26875,-0.043985153,0.056258213,0 -502,-85.28235294,27.26875,-0.109166818,-0.005222569,0 -503,-85.07058824,27.26875,-0.032172276,-0.067639461,0 -504,-84.85882353,27.26875,0.026675478,-0.123010238,0 -505,-84.64705882,27.26875,0.050188383,-0.148461343,0 -506,-84.43529412,27.26875,0.051880923,-0.111808027,0 -507,-84.22352941,27.26875,0.028863826,-0.057332517,0 -508,-84.01176471,27.26875,-0.001427943,0.000908297,0 -509,-83.8,27.26875,-0.008136132,-0.020744734,0 -510,-90.78823529,27.5,0.034586975,-0.00517708,0 -511,-90.57647059,27.5,0.045215341,-0.057366413,0 -512,-90.36470588,27.5,0.071203049,-0.05184804,0 -513,-90.15294118,27.5,0.018589814,-0.051766273,0 -514,-89.94117647,27.5,0.031617283,-0.030409466,0 -515,-89.72941176,27.5,0.012284385,0.008082718,0 -516,-89.51764706,27.5,0.007553237,-0.011886523,0 -517,-89.30588235,27.5,-0.023118993,-0.109285054,0 -518,-89.09411765,27.5,-0.083566282,-0.214842918,0 -519,-88.88235294,27.5,-0.106612636,-0.186920593,0 -520,-88.67058824,27.5,0.072700665,-0.105248583,0 -521,-88.45882353,27.5,0.098090664,-0.122978414,0 -522,-88.24705882,27.5,0.041087497,-0.11927343,0 -523,-88.03529412,27.5,0.020582796,-0.121571589,0 -524,-87.82352941,27.5,-0.009243939,-0.141193291,0 -525,-87.61176471,27.5,-0.038827059,-0.021121758,0 -526,-87.4,27.5,-0.026887325,-0.008190579,0 -527,-87.18823529,27.5,-0.048391747,-0.003517729,0 -528,-86.97647059,27.5,-0.037227437,-0.049473375,0 -529,-86.76470588,27.5,-0.07773177,0.02807183,0 -530,-86.55294118,27.5,-0.14957728,0.080787088,0 -531,-86.34117647,27.5,-0.157985323,0.120579472,0 -532,-86.12941176,27.5,-0.139373904,0.10813917,0 -533,-85.91764706,27.5,-0.096610935,0.094576271,0 -534,-85.70588235,27.5,-0.084337462,0.073564149,0 -535,-85.49411765,27.5,-0.080913345,0.08207414,0 -536,-85.28235294,27.5,-0.026117701,-0.053440641,0 -537,-85.07058824,27.5,-0.008853652,-0.130690211,0 -538,-84.85882353,27.5,0.007536362,-0.098774007,0 -539,-84.64705882,27.5,0.017220944,-0.143542234,0 -540,-84.43529412,27.5,0.036156505,-0.140839446,0 -541,-84.22352941,27.5,0.01089513,0.000606245,0 -542,-84.01176471,27.5,0.006456676,-0.011532106,0 -543,-83.8,27.5,0.010180421,-0.005156976,0 diff --git a/docs/examples/data/gulfdata_train.csv b/docs/examples/data/gulfdata_train.csv deleted file mode 100644 index 7cdc4dc34..000000000 --- a/docs/examples/data/gulfdata_train.csv +++ /dev/null @@ -1,21 +0,0 @@ -,lon,lat,ubar,vbar -0,-90,26.5,0.017014439,-0.045338905 -1,-89.9353082,26.26236714,-0.027521352,-0.263696188 -2,-90.06139353,25.84260318,-0.151144052,-0.192281814 -3,-90.28714753,25.49465487,-0.149909671,-0.199497341 -4,-88.2,27,0.11553095,-0.181067045 -5,-87.90166407,26.67714267,0.384517986,-0.090623334 -6,-87.33337396,26.55351674,0.399623312,-0.18099943 -7,-86.76239529,26.33117253,0.414531666,-0.158313295 -8,-84.8,26,-0.044404483,-0.119692295 -9,-84.85842404,25.67073964,0.078196937,-0.374986066 -10,-84.84629796,25.05339588,0.04315034,-0.209116548 -11,-84.7794598,24.56733011,0.165777288,-0.334277532 -12,-86.1,24.8,-0.106249442,-0.282439498 -13,-86.3057102,24.47027326,-0.152320623,-0.108721538 -14,-86.55797559,24.33207825,-0.261465326,0.048502932 -15,-86.91782493,24.47417667,-0.278514359,0.023210374 -16,-89.2,25.1,-0.009065352,-0.065193047 -17,-89.17150107,24.88187548,0.087482163,-0.068463221 -18,-88.97508649,24.70856231,0.189755788,-0.051745985 -19,-88.6991099,24.68494422,0.02128361,0.07705565 diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index 16744a568..c9344d0bb 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -25,7 +25,6 @@ import matplotlib.pyplot as plt import optax as ox import pandas as pd -from sklearn.model_selection import train_test_split import tensorflow_probability as tfp with install_import_hook("gpjax", "beartype.beartype"): @@ -38,9 +37,6 @@ ) colors = rcParams["axes.prop_cycle"].by_key()["color"] -import dataclasses -from gpjax import Constant -from gpjax.base import static_field # %% [markdown] # ## Data Loading and problem setting @@ -70,12 +66,13 @@ def prepare_data(df): # loading in data -try: - gulf_data_train = pd.read_csv("data/gulfdata_train.csv") - gulf_data_test = pd.read_csv("data/gulfdata_test.csv") -except FileNotFoundError: - gulf_data_train = pd.read_csv("docs/examples/data/gulfdata_train.csv") - gulf_data_test = pd.read_csv("docs/examples/data/gulfdata_test.csv") + +gulf_data_train = pd.read_csv( + "https://raw.githubusercontent.com/JaxGaussianProcesses/gpjaxstatic/main/data/gulfdata_train.csv" +) +gulf_data_test = pd.read_csv( + "https://raw.githubusercontent.com/JaxGaussianProcesses/gpjaxstatic/main/data/gulfdata_test.csv" +) pos_test, vel_test, shape = prepare_data(gulf_data_test) @@ -83,7 +80,14 @@ def prepare_data(df): fig, ax = plt.subplots(1, 1) ax.quiver( - pos_test[0], pos_test[1], vel_test[0], vel_test[1], color=colors[0], label="$D_0$" + pos_test[0], + pos_test[1], + vel_test[0], + vel_test[1], + color=colors[0], + label="$D_0$", + angles="xy", + scale=10, ) ax.quiver( pos_train[0], @@ -93,6 +97,8 @@ def prepare_data(df): color=colors[1], alpha=0.7, label="$D_T$", + angles="xy", + scale=10, ) ax.legend() plt.show() @@ -150,14 +156,15 @@ def stack_velocity(data): return data.T.flatten().reshape(-1, 1) -pos_train3d = label_position(pos_train) -vel_train3d = stack_velocity(vel_train) +def dataset_3d(pos, vel): + return gpx.Dataset(label_position(pos), stack_velocity(vel)) -# we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points -pos_test3d = label_position(pos_test) -# place th etraining data into a Dataset object to be used by GPJax -DT = gpx.Dataset(X=pos_train3d, y=vel_train3d) +# label and place the training data into a Dataset object to be used by GPJax +dataset_train = dataset_3d(pos_train, vel_train) + +# we also require the testing data to be relabelled for later use, such that we can query the 2Nx2N GP at the test points +dataset_ground_truth = dataset_3d(pos_test, vel_test) # %% [markdown] @@ -170,13 +177,13 @@ def stack_velocity(data): # # where $k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)$ are the user chosen kernels for each dimension. What this means is that there are no correlations between the $x^{(0)}$ and $x^{(1)}$ dimensions for all choices $\mathbf{X}$ and $\mathbf{X}^{\prime}$, since there are no off-diagonal elements in the Gram matrix populated by this choice. # -# To implement this approach in GPJax, we define `velocity_kernel` in the following cell, following the steps outlined in the [custom kernels notebook](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels/#custom-kernel). This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. +# To implement this approach in GPJax, we define `VelocityKernel` in the following cell, following the steps outlined in the [custom kernels notebook](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels/#custom-kernel). This modular implementation takes the choice of user kernels as its class attributes: `kernel0` and `kernel1`. We must additionally pass the argument `active_dims = [0,1]`, which is an attribute of the base class `AbstractKernel`, into the chosen kernels. This is necessary such that the subsequent likelihood optimisation does not optimise over the artificial label dimension. # # %% @dataclass -class velocity_kernel(gpx.kernels.AbstractKernel): +class VelocityKernel(gpx.kernels.AbstractKernel): kernel0: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) kernel1: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) @@ -213,8 +220,8 @@ def initialise_gp(kernel, mean, dataset): # Define the velocity GP mean = gpx.mean_functions.Zero() -kernel = velocity_kernel() -velocity_posterior = initialise_gp(kernel, mean, DT) +kernel = VelocityKernel() +velocity_posterior = initialise_gp(kernel, mean, dataset_train) # %% [markdown] @@ -223,7 +230,7 @@ def initialise_gp(kernel, mean, dataset): # %% def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): - # define the Marginal Log likelihood using DT + # define the Marginal Log likelihood using dataset_train objective = gpx.objectives.ConjugateMLL(negative=True) # Optimise to minimise the MLL optimiser = ox.adam(learning_rate=0.1) @@ -245,7 +252,7 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): return opt_posterior -opt_velocity_posterior = optimise_mll(velocity_posterior, DT) +opt_velocity_posterior = optimise_mll(velocity_posterior, dataset_train) # %% [markdown] @@ -254,18 +261,19 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): # %% -def latent_distribution(opt_posterior, pos_3d): - latent = opt_posterior.predict(pos_3d, train_data=DT) +def latent_distribution(opt_posterior, pos_3d, dataset_train): + latent = opt_posterior.predict(pos_3d, train_data=dataset_train) latent_mean = latent.mean() latent_std = latent.stddev() return latent_mean, latent_std # extract latent mean and std of g, redistribute into vectors to model F -velocity_mean, velocity_std = latent_distribution(opt_velocity_posterior, pos_test3d) +velocity_mean, velocity_std = latent_distribution( + opt_velocity_posterior, dataset_ground_truth.X, dataset_train +) -vel_lat = [velocity_mean[::2], velocity_mean[1::2]] -pos_lat = pos_test +dataset_latent_velocity = dataset_3d(pos_test, velocity_mean) # %% [markdown] @@ -274,107 +282,93 @@ def latent_distribution(opt_posterior, pos_3d): # %% # Residuals between ground truth and estimate -def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape): - Y = pos_test[1] - X = pos_test[0] - # make figure - fig, ax = plt.subplots(1, 3, figsize=(12, 3)) - fig.tight_layout() - # ground truth - ax[0].quiver( - pos_test[0], - pos_test[1], - vel_test[0], - vel_test[1], - color=colors[0], - label="Training data", - scale=10, - ) - ax[0].quiver( - pos_train[0], - pos_train[1], - vel_train[0], - vel_train[1], - color=colors[1], - label="Test Data", - scale=10, + + +def plot_vector_field(ax, dataset, **kwargs): + ax.quiver( + dataset.X[::2][:, 0], + dataset.X[::2][:, 1], + dataset.y[::2], + dataset.y[1::2], + **kwargs, ) - ax[0].set( + + +def prepare_ax(ax, X, Y, title, **kwargs): + ax.set( xlim=[X.min() - 0.1, X.max() + 0.1], ylim=[Y.min() + 0.1, Y.max() + 0.1], aspect="equal", - title="Ground Truth", + title=title, + ylabel="latitude", + **kwargs, ) - # Latent estimate of vector field F - ax[1].quiver( - pos_lat[0], - pos_lat[1], - vel_lat[0], - vel_lat[1], - color=colors[3], - label="Latent estimate of Ground Truth", - scale=10, + +def residuals(dataset_latent, dataset_ground_truth): + return jnp.sqrt( + (dataset_latent.y[::2] - dataset_ground_truth.y[::2]) ** 2 + + (dataset_latent.y[1::2] - dataset_ground_truth.y[1::2]) ** 2 ) - ax[1].quiver( - pos_train[0], - pos_train[1], - vel_train[0], - vel_train[1], + + +def plot_fields( + dataset_ground_truth, dataset_trajectory, dataset_latent, shape=shape, scale=10 +): + X = dataset_ground_truth.X[:, 0][::2] + Y = dataset_ground_truth.X[:, 1][::2] + # make figure + fig, ax = plt.subplots(1, 3, figsize=(12.0, 2.7), sharey=True) + + # ground truth + plot_vector_field( + ax[0], + dataset_ground_truth, + color=colors[0], + label="Ocean Current", + angles="xy", + scale=scale, + ) + plot_vector_field( + ax[0], + dataset_trajectory, color=colors[1], - scale=10, + label="Drifter", + angles="xy", + scale=scale, ) - ax[1].set( - xlim=[X.min() - 0.1, X.max() + 0.1], - ylim=[Y.min() + 0.1, Y.max() + 0.1], - aspect="equal", - title="GP Latent Estimate", + prepare_ax(ax[0], X, Y, "Ground Truth") + + # Latent estimate of vector field F + plot_vector_field(ax[1], dataset_latent, color=colors[0], angles="xy", scale=scale) + plot_vector_field( + ax[1], dataset_trajectory, color=colors[1], angles="xy", scale=scale ) + prepare_ax(ax[1], X, Y, "GP Estimate", xlabel="Longitude") # residuals residuals_vel = jnp.flip( - jnp.sqrt( - (vel_test[0] - vel_lat[0]) ** 2 + (vel_test[1] - vel_lat[1]) ** 2 - ).reshape(shape), - axis=[0], + residuals(dataset_latent, dataset_ground_truth).reshape(shape), axis=0 ) im = ax[2].imshow( - residuals_vel, extent=[X.min(), X.max(), Y.min(), Y.max()], cmap="winter" + residuals_vel, + extent=[X.min(), X.max(), Y.min(), Y.max()], + cmap="jet", + vmin=0, + vmax=1.0, + interpolation="spline36", ) - - ax[2].quiver( - pos_test[0], - pos_test[1], - vel_lat[0] - vel_test[0], - vel_lat[1] - vel_test[1], - color="white", - scale=10, - ) - ax[2].quiver( - pos_train[0], - pos_train[1], - vel_train[0], - vel_train[1], - color=colors[1], - scale=10, - ) - ax[2].set( - xlim=[X.min() - 0.1, X.max() + 0.1], - ylim=[Y.min() + 0.1, Y.max() + 0.1], - aspect="equal", - title="Residuals", + plot_vector_field( + ax[2], dataset_trajectory, color=colors[1], angles="xy", scale=scale ) + prepare_ax(ax[2], X, Y, "Residuals", xlabel="Longitude") + fig.colorbar(im, fraction=0.027, pad=0.04, orientation="vertical") - fig.colorbar( - im, - fraction=0.027, - pad=0.04, - orientation="vertical", - ) + fig.legend(loc="lower center", framealpha=0.0, ncols=3, fontsize="medium") plt.show() -plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape) +plot_fields(dataset_ground_truth, dataset_train, dataset_latent_velocity) # %% [markdown] @@ -425,7 +419,7 @@ def plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shap # for either $z$. # %% @dataclass -class helmholtz_kernel(gpx.kernels.AbstractKernel): +class HelmholtzKernel(gpx.kernels.AbstractKernel): # initialise Phi and Psi kernels as any stationary kernel in gpJax potential_kernel: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) stream_kernel: gpx.kernels.AbstractKernel = gpx.kernels.RBF(active_dims=[0, 1]) @@ -451,14 +445,14 @@ def __call__( # %% [markdown] # ### GPJax Implementation -# We repeat the exact same steps as with the velocity GP model, but replacing `velocity_kernel` with `helmholtz_kernel`. +# We repeat the exact same steps as with the velocity GP model, but replacing `VelocityKernel` with `HelmholtzKernel`. # %% # Redefine Gaussian process with Helmholtz kernel -kernel = helmholtz_kernel() -helmholtz_posterior = initialise_gp(kernel, mean, DT) +kernel = HelmholtzKernel() +helmholtz_posterior = initialise_gp(kernel, mean, dataset_train) # Optimise hyperparameters using optax -opt_helmholtz_posterior = optimise_mll(helmholtz_posterior, DT) +opt_helmholtz_posterior = optimise_mll(helmholtz_posterior, dataset_train) # %% [markdown] @@ -467,11 +461,12 @@ def __call__( # %% # obtain latent distribution, extract x and y values over g -helmholtz_mean, helmholtz_std = latent_distribution(opt_helmholtz_posterior, pos_test3d) -vel_lat = [helmholtz_mean[::2], helmholtz_mean[1::2]] -pos_lat = pos_test +helmholtz_mean, helmholtz_std = latent_distribution( + opt_helmholtz_posterior, dataset_ground_truth.X, dataset_train +) +dataset_latent_helmholtz = dataset_3d(pos_test, helmholtz_mean) -plot_fields(pos_train, pos_test, vel_train, vel_test, pos_lat, vel_lat, shape) +plot_fields(dataset_ground_truth, dataset_train, dataset_latent_helmholtz) # %% [markdown] # Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). From acc6291c8da6957e30eea0c96cd01f045af74423 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Thu, 17 Aug 2023 21:32:42 +0100 Subject: [PATCH 55/76] Refactor kernel computation to cola, so tests pass on gpjax.kernels --- gpjax/kernels/computations/base.py | 20 +++++++------- gpjax/kernels/computations/basis_functions.py | 11 +++++--- .../kernels/computations/constant_diagonal.py | 26 ++++++++----------- gpjax/kernels/computations/diagonal.py | 8 +++--- tests/conftest.py | 8 +++--- tests/test_kernels/test_approximations.py | 4 +-- tests/test_kernels/test_non_euclidean.py | 11 +++++--- tests/test_kernels/test_nonstationary.py | 2 +- tests/test_kernels/test_stationary.py | 2 +- 9 files changed, 46 insertions(+), 46 deletions(-) diff --git a/gpjax/kernels/computations/base.py b/gpjax/kernels/computations/base.py index 6f1ce345f..5b6ab0b18 100644 --- a/gpjax/kernels/computations/base.py +++ b/gpjax/kernels/computations/base.py @@ -17,17 +17,17 @@ from dataclasses import dataclass import typing as tp +from cola.ops import ( + Dense, + Diagonal, + LinearOperator, +) from jax import vmap from jaxtyping import ( Float, Num, ) -from gpjax.linops import ( - DenseLinearOperator, - DiagonalLinearOperator, - LinearOperator, -) from gpjax.typing import Array Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 @@ -53,7 +53,7 @@ def gram( LinearOperator: Gram covariance operator of the kernel function. """ Kxx = self.cross_covariance(kernel, x, x) - return DenseLinearOperator(Kxx) + return Dense(Kxx) @abc.abstractmethod def cross_covariance( @@ -73,9 +73,7 @@ def cross_covariance( """ raise NotImplementedError - def diagonal( - self, kernel: Kernel, inputs: Num[Array, "N D"] - ) -> DiagonalLinearOperator: + def diagonal(self, kernel: Kernel, inputs: Num[Array, "N D"]) -> Diagonal: r"""For a given kernel, compute the elementwise diagonal of the NxN gram matrix on an input matrix of shape NxD. @@ -85,6 +83,6 @@ def diagonal( Returns ------- - DiagonalLinearOperator: The computed diagonal variance entries. + Diagonal: The computed diagonal variance entries. """ - return DiagonalLinearOperator(diag=vmap(lambda x: kernel(x, x))(inputs)) + return Diagonal(diag=vmap(lambda x: kernel(x, x))(inputs)) diff --git a/gpjax/kernels/computations/basis_functions.py b/gpjax/kernels/computations/basis_functions.py index 1141378e5..c87d18443 100644 --- a/gpjax/kernels/computations/basis_functions.py +++ b/gpjax/kernels/computations/basis_functions.py @@ -5,11 +5,14 @@ from jaxtyping import Float from gpjax.kernels.computations.base import AbstractKernelComputation -from gpjax.linops import DenseLinearOperator from gpjax.typing import Array Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 +from cola.ops import Dense + +# TODO: Use low rank linear operator! + @dataclass class BasisFunctionComputation(AbstractKernelComputation): @@ -34,7 +37,7 @@ def cross_covariance( z2 = self.compute_features(kernel, y) return self.scaling(kernel) * jnp.matmul(z1, z2.T) - def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> DenseLinearOperator: + def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Dense: r"""Compute an approximate Gram matrix. For the Gram matrix, we can save computations by computing only one matrix @@ -45,11 +48,11 @@ def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> DenseLinearOperat inputs (Float[Array, "N D"]): A $`N x D`$ array of inputs. Returns: - DenseLinearOperator: A dense linear operator representing the + Dense: A dense linear operator representing the $`N \times N`$ Gram matrix. """ z1 = self.compute_features(kernel, inputs) - return DenseLinearOperator(self.scaling(kernel) * jnp.matmul(z1, z1.T)) + return Dense(self.scaling(kernel) * jnp.matmul(z1, z1.T)) def compute_features( self, kernel: Kernel, x: Float[Array, "N D"] diff --git a/gpjax/kernels/computations/constant_diagonal.py b/gpjax/kernels/computations/constant_diagonal.py index 4e6c1afd7..7748154df 100644 --- a/gpjax/kernels/computations/constant_diagonal.py +++ b/gpjax/kernels/computations/constant_diagonal.py @@ -15,24 +15,22 @@ import typing as tp +from cola.ops import ( + Diagonal, + Identity, +) from jax import vmap import jax.numpy as jnp from jaxtyping import Float from gpjax.kernels.computations import AbstractKernelComputation -from gpjax.linops import ( - ConstantDiagonalLinearOperator, - DiagonalLinearOperator, -) from gpjax.typing import Array Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 class ConstantDiagonalKernelComputation(AbstractKernelComputation): - def gram( - self, kernel: Kernel, x: Float[Array, "N D"] - ) -> ConstantDiagonalLinearOperator: + def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> Diagonal: r"""Compute the Gram matrix. Compute Gram covariance operator of the kernel function. @@ -42,14 +40,12 @@ def gram( x (Float[Array, "N N"]): The inputs to the kernel function. """ value = kernel(x[0], x[0]) + dtype = value.dtype + shape = (x.shape[0], x.shape[0]) - return ConstantDiagonalLinearOperator( - value=jnp.atleast_1d(value), size=x.shape[0] - ) + return jnp.atleast_1d(value) * Identity(shape=shape, dtype=dtype) - def diagonal( - self, kernel: Kernel, inputs: Float[Array, "N D"] - ) -> DiagonalLinearOperator: + def diagonal(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Diagonal: r"""Compute the diagonal Gram matrix's entries. For a given kernel, compute the elementwise diagonal of the @@ -61,11 +57,11 @@ def diagonal( Returns ------- - DiagonalLinearOperator: The computed diagonal variance entries. + Diagonal: The computed diagonal variance entries. """ diag = vmap(lambda x: kernel(x, x))(inputs) - return DiagonalLinearOperator(diag=diag) + return Diagonal(diag=diag) def cross_covariance( self, kernel: Kernel, x: Float[Array, "N D"], y: Float[Array, "M D"] diff --git a/gpjax/kernels/computations/diagonal.py b/gpjax/kernels/computations/diagonal.py index 8703cc753..266ca4165 100644 --- a/gpjax/kernels/computations/diagonal.py +++ b/gpjax/kernels/computations/diagonal.py @@ -14,11 +14,11 @@ # ============================================================================== import beartype.typing as tp +from cola.ops import Diagonal from jax import vmap from jaxtyping import Float from gpjax.kernels.computations import AbstractKernelComputation -from gpjax.linops import DiagonalLinearOperator from gpjax.typing import Array Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 @@ -29,7 +29,7 @@ class DiagonalKernelComputation(AbstractKernelComputation): a diagonal Gram matrix. """ - def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> DiagonalLinearOperator: + def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> Diagonal: r"""Compute the Gram matrix. For a kernel with diagonal structure, compute the $`N\times N`$ Gram matrix on @@ -41,9 +41,9 @@ def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> DiagonalLinearOperator Returns ------- - DiagonalLinearOperator: The computed square Gram matrix. + Diagonal: The computed square Gram matrix. """ - return DiagonalLinearOperator(diag=vmap(lambda x: kernel(x, x))(x)) + return Diagonal(diag=vmap(lambda x: kernel(x, x))(x)) def cross_covariance( self, kernel: Kernel, x: Float[Array, "N D"], y: Float[Array, "M D"] diff --git a/tests/conftest.py b/tests/conftest.py index e12a1f72d..451074f1f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ -from jaxtyping import install_import_hook +# from jaxtyping import install_import_hook -# import gpjax within import hook to apply beartype everywhere, before running tests -with install_import_hook("gpjax", "beartype.beartype"): - import gpjax # noqa: F401 +# # import gpjax within import hook to apply beartype everywhere, before running tests +# with install_import_hook("gpjax", "beartype.beartype"): +# import gpjax # noqa: F401 diff --git a/tests/test_kernels/test_approximations.py b/tests/test_kernels/test_approximations.py index f5d983d76..b1bb94902 100644 --- a/tests/test_kernels/test_approximations.py +++ b/tests/test_kernels/test_approximations.py @@ -1,5 +1,6 @@ from typing import Tuple +from cola.ops import Dense import jax from jax.config import config import jax.numpy as jnp @@ -21,7 +22,6 @@ PoweredExponential, RationalQuadratic, ) -from gpjax.linops import DenseLinearOperator config.update("jax_enable_x64", True) _jitter = 1e-6 @@ -51,7 +51,7 @@ def test_gram(kernel: AbstractKernel, num_basis_fns: int, n_dims: int, n_data: i linop = approximate.gram(x) # Check the return type - assert isinstance(linop, DenseLinearOperator) + assert isinstance(linop, Dense) Kxx = linop.to_dense() + jnp.eye(n_data) * _jitter diff --git a/tests/test_kernels/test_non_euclidean.py b/tests/test_kernels/test_non_euclidean.py index bdcb91b98..ffad0191f 100644 --- a/tests/test_kernels/test_non_euclidean.py +++ b/tests/test_kernels/test_non_euclidean.py @@ -10,13 +10,16 @@ # # See the License for the specific language governing permissions and # # limitations under the License. +from cola.ops import I_like from jax.config import config import jax.numpy as jnp +import jax.random as jr import networkx as nx -from gpjax.kernels.non_euclidean import GraphKernel, CatKernel -from gpjax.linops import identity -import jax.random as jr +from gpjax.kernels.non_euclidean import ( + CatKernel, + GraphKernel, +) # # Enable Float64 for more stable matrix inversions. config.update("jax_enable_x64", True) @@ -44,7 +47,7 @@ def test_graph_kernel(): assert Kxx.shape == (n_verticies, n_verticies) # Check positive definiteness - Kxx += identity(n_verticies) * 1e-6 + Kxx += I_like(Kxx) * 1e-6 eigen_values = jnp.linalg.eigvalsh(Kxx.to_dense()) assert all(eigen_values > 0) diff --git a/tests/test_kernels/test_nonstationary.py b/tests/test_kernels/test_nonstationary.py index b9b596cf7..a8fd98230 100644 --- a/tests/test_kernels/test_nonstationary.py +++ b/tests/test_kernels/test_nonstationary.py @@ -16,6 +16,7 @@ from itertools import product from typing import List +from cola.ops import LinearOperator import jax from jax.config import config import jax.numpy as jnp @@ -34,7 +35,6 @@ Linear, Polynomial, ) -from gpjax.linops import LinearOperator # Enable Float64 for more stable matrix inversions. config.update("jax_enable_x64", True) diff --git a/tests/test_kernels/test_stationary.py b/tests/test_kernels/test_stationary.py index 8a4717d18..5982494e0 100644 --- a/tests/test_kernels/test_stationary.py +++ b/tests/test_kernels/test_stationary.py @@ -17,6 +17,7 @@ from dataclasses import is_dataclass from itertools import product +from cola.ops import LinearOperator import jax from jax.config import config import jax.numpy as jnp @@ -42,7 +43,6 @@ White, ) from gpjax.kernels.stationary.utils import build_student_t_distribution -from gpjax.linops import LinearOperator # Enable Float64 for more stable matrix inversions. config.update("jax_enable_x64", True) From 2ce6c03116c5b64610bc841342fdee9af6ed5398 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Tue, 22 Aug 2023 14:07:02 +0100 Subject: [PATCH 56/76] Refactor more. --- gpjax/gaussian_distribution.py | 41 ++++--- gpjax/gps.py | 52 +++++---- gpjax/kernels/computations/base.py | 3 +- gpjax/kernels/computations/basis_functions.py | 3 +- gpjax/objectives.py | 27 +++-- gpjax/variational_families.py | 110 ++++++++---------- tests/test_gaussian_distribution.py | 20 ++-- 7 files changed, 133 insertions(+), 123 deletions(-) diff --git a/gpjax/gaussian_distribution.py b/gpjax/gaussian_distribution.py index e0125b746..e8d179f05 100644 --- a/gpjax/gaussian_distribution.py +++ b/gpjax/gaussian_distribution.py @@ -19,6 +19,8 @@ Optional, Tuple, ) +import cola +from cola.ops import Identity from jax import vmap import jax.numpy as jnp import jax.random as jr @@ -28,10 +30,6 @@ ) import tensorflow_probability.substrates.jax as tfp -from gpjax.linops import ( - IdentityLinearOperator, - LinearOperator, -) from gpjax.typing import ( Array, KeyArray, @@ -49,13 +47,13 @@ def _check_loc_scale(loc: Optional[Any], scale: Optional[Any]) -> None: if loc is not None and loc.ndim < 1: raise ValueError("The parameter `loc` must have at least one dimension.") - if scale is not None and scale.ndim < 2: + if scale is not None and len(scale.shape) < 2: # scale.ndim < 2: raise ValueError( "The `scale` must have at least two dimensions, but " f"`scale.shape = {scale.shape}`." ) - if scale is not None and not isinstance(scale, LinearOperator): + if scale is not None and not isinstance(scale, cola.LinearOperator): raise ValueError( f"scale must be a LinearOperator or a JAX array, but got {type(scale)}" ) @@ -79,7 +77,7 @@ class GaussianDistribution(tfd.Distribution): Args: loc (Optional[Float[Array, " N"]]): The mean of the distribution. Defaults to None. - scale (Optional[LinearOperator]): The scale matrix of the distribution. Defaults to None. + scale (Optional[cola.LinearOperator]): The scale matrix of the distribution. Defaults to None. Returns ------- @@ -94,7 +92,7 @@ class GaussianDistribution(tfd.Distribution): def __init__( self, loc: Optional[Float[Array, " N"]] = None, - scale: Optional[LinearOperator] = None, + scale: Optional[cola.LinearOperator] = None, ) -> None: r"""Initialises the distribution.""" _check_loc_scale(loc, scale) @@ -112,7 +110,7 @@ def __init__( # If not specified, set the scale to the identity matrix. if scale is None: - scale = IdentityLinearOperator(num_dims) + scale = Identity(shape=(num_dims, num_dims), dtype=loc.dtype) self.loc = loc self.scale = scale @@ -135,11 +133,11 @@ def covariance(self) -> Float[Array, "N N"]: def variance(self) -> Float[Array, " N"]: r"""Calculates the variance.""" - return self.scale.diagonal() + return cola.diag(self.scale) def stddev(self) -> Float[Array, " N"]: r"""Calculates the standard deviation.""" - return jnp.sqrt(self.scale.diagonal()) + return jnp.sqrt(cola.diag(self.scale)) @property def event_shape(self) -> Tuple: @@ -149,7 +147,8 @@ def event_shape(self) -> Tuple: def entropy(self) -> ScalarFloat: r"""Calculates the entropy of the distribution.""" return 0.5 * ( - self.event_shape[0] * (1.0 + jnp.log(2.0 * jnp.pi)) + self.scale.log_det() + self.event_shape[0] * (1.0 + jnp.log(2.0 * jnp.pi)) + + cola.logdet(self.scale) ) def log_prob( @@ -181,7 +180,9 @@ def log_prob( # compute the pdf, -1/2[ n log(2π) + log|Σ| + (y - µ)ᵀΣ⁻¹(y - µ) ] return -0.5 * ( - n * jnp.log(2.0 * jnp.pi) + sigma.log_det() + diff.T @ sigma.solve(diff) + n * jnp.log(2.0 * jnp.pi) + + cola.logdet(sigma) + + diff.T @ cola.solve(sigma, diff) ) def _sample_n(self, key: KeyArray, n: int) -> Float[Array, "n N"]: @@ -195,7 +196,7 @@ def _sample_n(self, key: KeyArray, n: int) -> Float[Array, "n N"]: Float[Array, "n N"]: The samples. """ # Obtain covariance root. - sqrt = self.scale.to_root() + sqrt = cola.sqrt(self.scale) # Gather n samples from standard normal distribution Z = [z₁, ..., zₙ]ᵀ. Z = jr.normal(key, shape=(n, *self.event_shape)) @@ -263,24 +264,26 @@ def _kl_divergence(q: GaussianDistribution, p: GaussianDistribution) -> ScalarFl sigma_p = p.scale # Find covariance roots. - sqrt_p = sigma_p.to_root() - sqrt_q = sigma_q.to_root() + sqrt_p = cola.sqrt(sigma_p) + sqrt_q = cola.sqrt(sigma_q) # diff, μp - μq diff = mu_p - mu_q # trace term, tr[Σp⁻¹ Σq] = tr[(LpLpᵀ)⁻¹(LqLqᵀ)] = tr[(Lp⁻¹Lq)(Lp⁻¹Lq)ᵀ] = (fr[LqLp⁻¹])² trace = _frobenius_norm_squared( - sqrt_p.solve(sqrt_q.to_dense()) + cola.solve(sqrt_p, sqrt_q.to_dense()) ) # TODO: Not most efficient, given the `to_dense()` call (e.g., consider diagonal p and q). Need to abstract solving linear operator against another linear operator. # Mahalanobis term, (μp - μq)ᵀ Σp⁻¹ (μp - μq) = tr [(μp - μq)ᵀ [LpLpᵀ]⁻¹ (μp - μq)] = (fr[Lp⁻¹(μp - μq)])² mahalanobis = jnp.sum( - jnp.square(sqrt_p.solve(diff)) + jnp.square(cola.solve(sqrt_p, diff)) ) # TODO: Need to improve this. Perhaps add a Mahalanobis method to ``LinearOperator``s. # KL[q(x)||p(x)] = [ [(μp - μq)ᵀ Σp⁻¹ (μp - μq)] - n - log|Σq| + log|Σp| + tr[Σp⁻¹ Σq] ] / 2 - return (mahalanobis - n_dim - sigma_q.log_det() + sigma_p.log_det() + trace) / 2.0 + return ( + mahalanobis - n_dim - cola.logdet(sigma_q) + cola.logdet(sigma_p) + trace + ) / 2.0 __all__ = [ diff --git a/gpjax/gps.py b/gpjax/gps.py index ec8c1f402..99ff6d6ad 100644 --- a/gpjax/gps.py +++ b/gpjax/gps.py @@ -23,6 +23,9 @@ Callable, Optional, ) +import cola +from cola.ops import Dense + import jax.numpy as jnp from jax.random import ( PRNGKey, @@ -47,7 +50,6 @@ Gaussian, NonGaussianLikelihood, ) -from gpjax.linops import identity from gpjax.mean_functions import AbstractMeanFunction from gpjax.typing import ( Array, @@ -243,7 +245,8 @@ def predict(self, test_inputs: Num[Array, "N D"]) -> GaussianDistribution: x = test_inputs mx = self.mean_function(x) Kxx = self.kernel.gram(x) - Kxx += identity(x.shape[0]) * self.jitter + Kxx += cola.ops.I_like(Kxx) * self.jitter + Kxx = cola.PSD(Kxx) return GaussianDistribution(jnp.atleast_1d(mx.squeeze()), Kxx) @@ -476,30 +479,28 @@ def predict( distribution as a `GaussianDistribution`. """ # Unpack training data - x, y, n, mask = train_data.X, train_data.y, train_data.n, train_data.mask + x, y, n_test, mask = train_data.X, train_data.y, train_data.n, train_data.mask # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs # Observation noise o² obs_noise = self.likelihood.obs_noise mx = self.prior.mean_function(x) # Precompute Gram matrix, Kxx, at training inputs, x - Kxx = self.prior.kernel.gram(x) + (identity(n) * self.prior.jitter) + Kxx = self.prior.kernel.gram(x) + Kxx += cola.ops.I_like(Kxx) * self.jitter # Σ = Kxx + Io² - Sigma = Kxx + identity(n) * obs_noise + Sigma = Kxx + cola.ops.I_like(Kxx) * obs_noise + Sigma = cola.PSD(Sigma) if mask is not None: y = jnp.where(mask, 0.0, y) mx = jnp.where(mask, 0.0, mx) - Sigma_masked = jnp.where(mask + mask.T, 0.0, Sigma.matrix) - Sigma = Sigma.replace( - matrix=jnp.where( - jnp.diag(jnp.squeeze(mask)), 1 / (2 * jnp.pi), Sigma_masked - ) - ) + Sigma_masked = jnp.where(mask + mask.T, 0.0, Sigma.to_dense()) + Sigma = cola.PSD(Dense(jnp.where(jnp.diag(jnp.squeeze(mask)), 1 / (2 * jnp.pi), Sigma_masked))) mean_t = self.prior.mean_function(t) Ktt = self.prior.kernel.gram(t) @@ -508,14 +509,15 @@ def predict( # Σ⁻¹ Kxt if mask is not None: Kxt = jnp.where(mask * jnp.ones((1, n_test), dtype=bool), 0.0, Kxt) - Sigma_inv_Kxt = Sigma.solve(Kxt) + Sigma_inv_Kxt = cola.solve(Sigma, Kxt) # μt + Ktx (Kxx + Io²)⁻¹ (y - μx) mean = mean_t + jnp.matmul(Sigma_inv_Kxt.T, y - mx) # Ktt - Ktx (Kxx + Io²)⁻¹ Kxt, TODO: Take advantage of covariance structure to compute Schur complement more efficiently. covariance = Ktt - jnp.matmul(Kxt.T, Sigma_inv_Kxt) - covariance += identity(n_test) * self.prior.jitter + covariance += cola.ops.I_like(covariance) * self.prior.jitter + covariance = cola.PSD(covariance) return GaussianDistribution(jnp.atleast_1d(mean.squeeze()), covariance) @@ -576,7 +578,7 @@ def sample_approx( # sample weights v for canonical features # v = Σ⁻¹ (y + ε - ɸ⍵) for Σ = Kxx + Io² and ε ᯈ N(0, o²) Kxx = self.prior.kernel.gram(train_data.X) # [N, N] - Sigma = Kxx + identity(train_data.n) * ( + Sigma = Kxx + cola.ops.I_like(Kxx) * ( self.likelihood.obs_noise + self.jitter ) # [N, N] eps = jnp.sqrt(self.likelihood.obs_noise) * normal( @@ -584,8 +586,8 @@ def sample_approx( ) # [N, B] y = train_data.y - self.prior.mean_function(train_data.X) # account for mean Phi = fourier_feature_fn(train_data.X) - canonical_weights = Sigma.solve( - y + eps - jnp.inner(Phi, fourier_weights) + canonical_weights = cola.solve( + Sigma, y + eps - jnp.inner(Phi, fourier_weights) ) # [N, B] def sample_fn(test_inputs: Float[Array, "n D"]) -> Float[Array, "n B"]: @@ -653,7 +655,7 @@ def predict( a `dx.Distribution`. """ # Unpack training data - x, n = train_data.X, train_data.n + x = train_data.X # Unpack mean function and kernel mean_function = self.prior.mean_function @@ -661,19 +663,20 @@ def predict( # Precompute lower triangular of Gram matrix, Lx, at training inputs, x Kxx = kernel.gram(x) - Kxx += identity(n) * self.prior.jitter - Lx = Kxx.to_root() + Kxx += cola.ops.I_like(Kxx) * self.prior.jitter + Kxx = cola.PSD(Kxx) + Lx = cola.sqrt(Kxx) # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs # Compute terms of the posterior predictive distribution Ktx = kernel.cross_covariance(t, x) - Ktt = kernel.gram(t) + identity(n_test) * self.prior.jitter + Ktt = kernel.gram(t) mean_t = mean_function(t) # Lx⁻¹ Kxt - Lx_inv_Kxt = Lx.solve(Ktx.T) + Lx_inv_Kxt = cola.solve(Lx, Ktx.T) # Whitened function values, wx, corresponding to the inputs, x wx = self.latent @@ -683,7 +686,8 @@ def predict( # Ktt - Ktx Kxx⁻¹ Kxt, TODO: Take advantage of covariance structure to compute Schur complement more efficiently. covariance = Ktt - jnp.matmul(Lx_inv_Kxt.T, Lx_inv_Kxt) - covariance += identity(n_test) * self.prior.jitter + covariance += cola.ops.I_like(covariance) * self.prior.jitter + covariance = cola.PSD(covariance) return GaussianDistribution(jnp.atleast_1d(mean.squeeze()), covariance) diff --git a/gpjax/kernels/computations/base.py b/gpjax/kernels/computations/base.py index 5b6ab0b18..d17121cac 100644 --- a/gpjax/kernels/computations/base.py +++ b/gpjax/kernels/computations/base.py @@ -17,6 +17,7 @@ from dataclasses import dataclass import typing as tp +from cola import PSD from cola.ops import ( Dense, Diagonal, @@ -53,7 +54,7 @@ def gram( LinearOperator: Gram covariance operator of the kernel function. """ Kxx = self.cross_covariance(kernel, x, x) - return Dense(Kxx) + return PSD(Dense(Kxx)) @abc.abstractmethod def cross_covariance( diff --git a/gpjax/kernels/computations/basis_functions.py b/gpjax/kernels/computations/basis_functions.py index c87d18443..7a3cd71fb 100644 --- a/gpjax/kernels/computations/basis_functions.py +++ b/gpjax/kernels/computations/basis_functions.py @@ -9,6 +9,7 @@ Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 +from cola import PSD from cola.ops import Dense # TODO: Use low rank linear operator! @@ -52,7 +53,7 @@ def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Dense: $`N \times N`$ Gram matrix. """ z1 = self.compute_features(kernel, inputs) - return Dense(self.scaling(kernel) * jnp.matmul(z1, z1.T)) + return PSD(Dense(self.scaling(kernel) * jnp.matmul(z1, z1.T))) def compute_features( self, kernel: Kernel, x: Float[Array, "N D"] diff --git a/gpjax/objectives.py b/gpjax/objectives.py index 8b1adbea0..35b943731 100644 --- a/gpjax/objectives.py +++ b/gpjax/objectives.py @@ -14,7 +14,6 @@ ) from gpjax.dataset import Dataset from gpjax.gaussian_distribution import GaussianDistribution -from gpjax.linops import identity from gpjax.typing import ( Array, ScalarFloat, @@ -22,6 +21,8 @@ tfd = tfp.distributions +import cola + @dataclass class AbstractObjective(Module): @@ -115,7 +116,7 @@ def step( ScalarFloat: The marginal log-likelihood of the Gaussian process for the current parameter set. """ - x, y, n = train_data.X, train_data.y, train_data.n + x, y = train_data.X, train_data.y # Observation noise o² obs_noise = posterior.likelihood.obs_noise @@ -123,8 +124,9 @@ def step( # Σ = (Kxx + Io²) = LLᵀ Kxx = posterior.prior.kernel.gram(x) - Kxx += identity(n) * posterior.prior.jitter - Sigma = Kxx + identity(n) * obs_noise + Kxx += cola.ops.I_like(Kxx) * posterior.prior.jitter + Sigma = Kxx + cola.ops.I_like(Kxx) * obs_noise + Sigma = cola.PSD(Sigma) # p(y | x, θ), where θ are the model hyperparameters: mll = GaussianDistribution(jnp.atleast_1d(mx.squeeze()), Sigma) @@ -169,10 +171,11 @@ def step( current parameter set. """ # Unpack the training data - x, y, n = data.X, data.y, data.n + x, y = data.X, data.y Kxx = posterior.prior.kernel.gram(x) - Kxx += identity(n) * posterior.prior.jitter - Lx = Kxx.to_root() + Kxx += cola.ops.I_like(Kxx) * posterior.prior.jitter + Kxx = cola.PSD(Kxx) + Lx = cola.sqrt(Kxx) # Compute the prior mean function mx = posterior.prior.mean_function(x) @@ -277,6 +280,9 @@ def q_moments(x): return expectation +# TODO: Replace code within CollapsedELBO to using (low rank structure of) LinOps and the GaussianDistribution object to be as succinct as e.g., the `ConjugateMLL`. + + class CollapsedELBO(AbstractObjective): r"""The collapsed evidence lower bound. @@ -322,12 +328,13 @@ def step( noise = variational_family.posterior.likelihood.obs_noise z = variational_family.inducing_inputs Kzz = kernel.gram(z) - Kzz += identity(m) * variational_family.jitter + Kzz += cola.ops.I_like(Kzz) * variational_family.jitter + Kzz = cola.PSD(Kzz) Kzx = kernel.cross_covariance(z, x) Kxx_diag = vmap(kernel, in_axes=(0, 0))(x, x) μx = mean_function(x) - Lz = Kzz.to_root() + Lz = cola.sqrt(Kzz) # Notation and derivation: # @@ -355,7 +362,7 @@ def step( # # with A and B defined as above. - A = Lz.solve(Kzx) / jnp.sqrt(noise) + A = cola.solve(Lz, Kzx) / jnp.sqrt(noise) # AAᵀ AAT = jnp.matmul(A, A.T) diff --git a/gpjax/variational_families.py b/gpjax/variational_families.py index 20c011739..64cbb38d3 100644 --- a/gpjax/variational_families.py +++ b/gpjax/variational_families.py @@ -17,6 +17,7 @@ from dataclasses import dataclass from beartype.typing import Any +import cola import jax.numpy as jnp import jax.scipy as jsp from jaxtyping import Float @@ -31,11 +32,6 @@ from gpjax.gaussian_distribution import GaussianDistribution from gpjax.gps import AbstractPosterior from gpjax.likelihoods import Gaussian -from gpjax.linops import ( - DenseLinearOperator, - LowerTriangularLinearOperator, - identity, -) from gpjax.typing import ( Array, ScalarFloat, @@ -145,7 +141,6 @@ def prior_kl(self) -> ScalarFloat: mu = self.variational_mean sqrt = self.variational_root_covariance z = self.inducing_inputs - m = self.num_inducing # Unpack mean function and kernel mean_function = self.posterior.prior.mean_function @@ -153,10 +148,10 @@ def prior_kl(self) -> ScalarFloat: muz = mean_function(z) Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter + Kzz = cola.PSD(Kzz + cola.ops.I_like(Kzz) * self.jitter) - sqrt = LowerTriangularLinearOperator.from_dense(sqrt) - S = DenseLinearOperator.from_root(sqrt) + sqrt = cola.ops.Triangular(sqrt) + S = sqrt @ sqrt.T qu = GaussianDistribution(loc=jnp.atleast_1d(mu.squeeze()), scale=S) pu = GaussianDistribution(loc=jnp.atleast_1d(muz.squeeze()), scale=Kzz) @@ -185,29 +180,28 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: mu = self.variational_mean sqrt = self.variational_root_covariance z = self.inducing_inputs - m = self.num_inducing # Unpack mean function and kernel mean_function = self.posterior.prior.mean_function kernel = self.posterior.prior.kernel Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter - Lz = Kzz.to_root() + Kzz += cola.ops.I_like(Kzz) * self.jitter + Lz = cola.sqrt(Kzz) muz = mean_function(z) # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs Ktt = kernel.gram(t) Kzt = kernel.cross_covariance(z, t) mut = mean_function(t) # Lz⁻¹ Kzt - Lz_inv_Kzt = Lz.solve(Kzt) + Lz_inv_Kzt = cola.solve(Lz, Kzt) # Kzz⁻¹ Kzt - Kzz_inv_Kzt = Lz.T.solve(Lz_inv_Kzt) + Kzz_inv_Kzt = cola.solve(Lz.T, Lz_inv_Kzt) # Ktz Kzz⁻¹ sqrt Ktz_Kzz_inv_sqrt = jnp.matmul(Kzz_inv_Kzt.T, sqrt) @@ -221,7 +215,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: - jnp.matmul(Lz_inv_Kzt.T, Lz_inv_Kzt) + jnp.matmul(Ktz_Kzz_inv_sqrt, Ktz_Kzz_inv_sqrt.T) ) - covariance += identity(n_test) * self.jitter + covariance += cola.ops.I_like(covariance) * self.jitter return GaussianDistribution( loc=jnp.atleast_1d(mean.squeeze()), scale=covariance @@ -258,10 +252,10 @@ def prior_kl(self) -> ScalarFloat: """ # Unpack variational parameters mu = self.variational_mean - sqrt = self.variational_root_covariance + sqrt = cola.ops.Triangular(self.variational_root_covariance) - sqrt = LowerTriangularLinearOperator.from_dense(sqrt) - S = DenseLinearOperator.from_root(sqrt) + # S = LLᵀ + S = sqrt @ sqrt.T # Compute whitened KL divergence qu = GaussianDistribution(loc=jnp.atleast_1d(mu.squeeze()), scale=S) @@ -290,25 +284,24 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: mu = self.variational_mean sqrt = self.variational_root_covariance z = self.inducing_inputs - m = self.num_inducing # Unpack mean function and kernel mean_function = self.posterior.prior.mean_function kernel = self.posterior.prior.kernel Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter - Lz = Kzz.to_root() + Kzz += cola.ops.I_like(Kzz) * self.jitter + Lz = cola.sqrt(Kzz) # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs Ktt = kernel.gram(t) Kzt = kernel.cross_covariance(z, t) mut = mean_function(t) # Lz⁻¹ Kzt - Lz_inv_Kzt = Lz.solve(Kzt) + Lz_inv_Kzt = cola.solve(Lz, Kzt) # Ktz Lz⁻ᵀ sqrt Ktz_Lz_invT_sqrt = jnp.matmul(Lz_inv_Kzt.T, sqrt) @@ -322,7 +315,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: - jnp.matmul(Lz_inv_Kzt.T, Lz_inv_Kzt) + jnp.matmul(Ktz_Lz_invT_sqrt, Ktz_Lz_invT_sqrt.T) ) - covariance += identity(n_test) * self.jitter + covariance += cola.ops.I_like(covariance) * self.jitter return GaussianDistribution( loc=jnp.atleast_1d(mean.squeeze()), scale=covariance @@ -391,17 +384,17 @@ def prior_kl(self) -> ScalarFloat: # L = (L⁻¹)⁻¹I sqrt = jsp.linalg.solve_triangular(sqrt_inv, jnp.eye(m), lower=True) - sqrt = LowerTriangularLinearOperator.from_dense(sqrt) + sqrt = cola.ops.Triangular(sqrt) # S = LLᵀ: - S = DenseLinearOperator.from_root(sqrt) + S = sqrt @ sqrt.T # μ = Sθ₁ mu = S @ natural_vector muz = mean_function(z) Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter + Kzz += cola.ops.I_like(Kzz) * self.jitter qu = GaussianDistribution(loc=jnp.atleast_1d(mu.squeeze()), scale=S) pu = GaussianDistribution(loc=jnp.atleast_1d(muz.squeeze()), scale=Kzz) @@ -453,22 +446,19 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: mu = jnp.matmul(S, natural_vector) Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter - Lz = Kzz.to_root() + Kzz += cola.ops.I_like(Kzz) * self.jitter + Lz = cola.sqrt(Kzz) muz = mean_function(z) - # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] - - Ktt = kernel.gram(t) - Kzt = kernel.cross_covariance(z, t) - mut = mean_function(t) + Ktt = kernel.gram(test_inputs) + Kzt = kernel.cross_covariance(z, test_inputs) + mut = mean_function(test_inputs) # Lz⁻¹ Kzt - Lz_inv_Kzt = Lz.solve(Kzt) + Lz_inv_Kzt = cola.solve(Lz, Kzt) # Kzz⁻¹ Kzt - Kzz_inv_Kzt = Lz.T.solve(Lz_inv_Kzt) + Kzz_inv_Kzt = cola.solve(Lz.T, Lz_inv_Kzt) # Ktz Kzz⁻¹ L Ktz_Kzz_inv_L = jnp.matmul(Kzz_inv_Kzt.T, sqrt) @@ -482,7 +472,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: - jnp.matmul(Lz_inv_Kzt.T, Lz_inv_Kzt) + jnp.matmul(Ktz_Kzz_inv_L, Ktz_Kzz_inv_L.T) ) - covariance += identity(n_test) * self.jitter + covariance += cola.ops.I_like(covariance) * self.jitter return GaussianDistribution( loc=jnp.atleast_1d(mean.squeeze()), scale=covariance @@ -538,7 +528,6 @@ def prior_kl(self) -> ScalarFloat: expectation_vector = self.expectation_vector expectation_matrix = self.expectation_matrix z = self.inducing_inputs - m = self.num_inducing # Unpack mean function and kernel mean_function = self.posterior.prior.mean_function @@ -549,12 +538,13 @@ def prior_kl(self) -> ScalarFloat: # S = η₂ - η₁ η₁ᵀ S = expectation_matrix - jnp.outer(mu, mu) - S = DenseLinearOperator(S) - S += identity(m) * self.jitter + S = cola.ops.Dense(S) + S = cola.PSD(S) + S += cola.ops.I_like(S) * self.jitter muz = mean_function(z) Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter + Kzz += cola.ops.I_like(Kzz) * self.jitter qu = GaussianDistribution(loc=jnp.atleast_1d(mu.squeeze()), scale=S) pu = GaussianDistribution(loc=jnp.atleast_1d(muz.squeeze()), scale=Kzz) @@ -584,7 +574,6 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: expectation_vector = self.expectation_vector expectation_matrix = self.expectation_matrix z = self.inducing_inputs - m = self.num_inducing # Unpack mean function and kernel mean_function = self.posterior.prior.mean_function @@ -595,29 +584,30 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: # S = η₂ - η₁ η₁ᵀ S = expectation_matrix - jnp.matmul(mu, mu.T) - S = DenseLinearOperator(S) - S += identity(m) * self.jitter + S = cola.ops.Dense(S) + S += cola.ops.I_like(S) * self.jitter + S = cola.PSD(S) # S = sqrt sqrtᵀ - sqrt = S.to_root().to_dense() + sqrt = cola.sqrt(S).to_dense() Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter - Lz = Kzz.to_root() + Kzz += cola.ops.I_like(Kzz) * self.jitter + Lz = cola.sqrt(Kzz) muz = mean_function(z) # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs Ktt = kernel.gram(t) Kzt = kernel.cross_covariance(z, t) mut = mean_function(t) # Lz⁻¹ Kzt - Lz_inv_Kzt = Lz.solve(Kzt) + Lz_inv_Kzt = cola.solve(Lz, Kzt) # Kzz⁻¹ Kzt - Kzz_inv_Kzt = Lz.T.solve(Lz_inv_Kzt) + Kzz_inv_Kzt = cola.solve(Lz.T, Lz_inv_Kzt) # Ktz Kzz⁻¹ sqrt Ktz_Kzz_inv_sqrt = jnp.matmul(Kzz_inv_Kzt.T, sqrt) @@ -631,7 +621,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: - jnp.matmul(Lz_inv_Kzt.T, Lz_inv_Kzt) + jnp.matmul(Ktz_Kzz_inv_sqrt, Ktz_Kzz_inv_sqrt.T) ) - covariance += identity(n_test) * self.jitter + covariance += cola.ops.I_like(covariance) * self.jitter return GaussianDistribution( loc=jnp.atleast_1d(mean.squeeze()), scale=covariance @@ -667,7 +657,7 @@ def predict( variational Gaussian process at the test inputs $t$. """ # Unpack test inputs - t, n_test = test_inputs, test_inputs.shape[0] + t = test_inputs # Unpack training data x, y = train_data.X, train_data.y @@ -683,13 +673,13 @@ def predict( Kzx = kernel.cross_covariance(z, x) Kzz = kernel.gram(z) - Kzz += identity(m) * self.jitter + Kzz += cola.ops.I_like(Kzz) * self.jitter # Lz Lzᵀ = Kzz - Lz = Kzz.to_root() + Lz = cola.sqrt(Kzz) # Lz⁻¹ Kzx - Lz_inv_Kzx = Lz.solve(Kzx) + Lz_inv_Kzx = cola.solve(Lz, Kzx) # A = Lz⁻¹ Kzt / o A = Lz_inv_Kzx / jnp.sqrt(noise) @@ -707,14 +697,14 @@ def predict( Lz_inv_Kzx_diff = jsp.linalg.cho_solve((L, True), jnp.matmul(Lz_inv_Kzx, diff)) # Kzz⁻¹ Kzx (y - μx) - Kzz_inv_Kzx_diff = Lz.T.solve(Lz_inv_Kzx_diff) + Kzz_inv_Kzx_diff = cola.solve(Lz.T, Lz_inv_Kzx_diff) Ktt = kernel.gram(t) Kzt = kernel.cross_covariance(z, t) mut = mean_function(t) # Lz⁻¹ Kzt - Lz_inv_Kzt = Lz.solve(Kzt) + Lz_inv_Kzt = cola.solve(Lz, Kzt) # L⁻¹ Lz⁻¹ Kzt L_inv_Lz_inv_Kzt = jsp.linalg.solve_triangular(L, Lz_inv_Kzt, lower=True) @@ -728,7 +718,7 @@ def predict( - jnp.matmul(Lz_inv_Kzt.T, Lz_inv_Kzt) + jnp.matmul(L_inv_Lz_inv_Kzt.T, L_inv_Lz_inv_Kzt) ) - covariance += identity(n_test) * self.jitter + covariance += cola.ops.I_like(covariance) * self.jitter return GaussianDistribution( loc=jnp.atleast_1d(mean.squeeze()), scale=covariance diff --git a/tests/test_gaussian_distribution.py b/tests/test_gaussian_distribution.py index 9db53327e..351ca7e31 100644 --- a/tests/test_gaussian_distribution.py +++ b/tests/test_gaussian_distribution.py @@ -23,9 +23,13 @@ # Enable Float64 for more stable matrix inversions. config.update("jax_enable_x64", True) +import cola +from cola.ops import ( + Dense, + Diagonal, +) + from gpjax.gaussian_distribution import GaussianDistribution -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator _key = jr.PRNGKey(seed=42) @@ -37,7 +41,7 @@ def approx_equal(res: jnp.ndarray, actual: jnp.ndarray) -> bool: """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 + return jnp.linalg.norm(res - actual) < 1e-5 @pytest.mark.parametrize("n", [1, 2, 5, 100]) @@ -49,7 +53,7 @@ def test_array_arguments(n: int) -> None: # check that cholesky does not error _L = jnp.linalg.cholesky(covariance) # noqa: F841 - dist = GaussianDistribution(loc=mean, scale=DenseLinearOperator(covariance)) + dist = GaussianDistribution(loc=mean, scale=cola.PSD(Dense(covariance))) assert approx_equal(dist.mean(), mean) assert approx_equal(dist.variance(), covariance.diagonal()) @@ -70,7 +74,7 @@ def test_diag_linear_operator(n: int) -> None: mean = jr.uniform(key_mean, shape=(n,)) diag = jr.uniform(key_diag, shape=(n,)) - dist_diag = GaussianDistribution(loc=mean, scale=DiagonalLinearOperator(diag**2)) + dist_diag = GaussianDistribution(loc=mean, scale=Diagonal(diag**2)) tfp_dist = MultivariateNormalDiag(loc=mean, scale_diag=diag) assert approx_equal(dist_diag.mean(), tfp_dist.mean()) @@ -101,7 +105,7 @@ def test_dense_linear_operator(n: int) -> None: sqrt = jnp.linalg.cholesky(covariance + jnp.eye(n) * 1e-10) - dist_dense = GaussianDistribution(loc=mean, scale=DenseLinearOperator(covariance)) + dist_dense = GaussianDistribution(loc=mean, scale=cola.PSD(Dense(covariance))) tfp_dist = MultivariateNormalFullCovariance(loc=mean, covariance_matrix=covariance) assert approx_equal(dist_dense.mean(), tfp_dist.mean()) @@ -132,8 +136,8 @@ def test_kl_divergence(n: int) -> None: covariance_a = sqrt_a @ sqrt_a.T covariance_b = sqrt_b @ sqrt_b.T - dist_a = GaussianDistribution(loc=mean_a, scale=DenseLinearOperator(covariance_a)) - dist_b = GaussianDistribution(loc=mean_b, scale=DenseLinearOperator(covariance_b)) + dist_a = GaussianDistribution(loc=mean_a, scale=cola.PSD(Dense(covariance_a))) + dist_b = GaussianDistribution(loc=mean_b, scale=cola.PSD(Dense(covariance_b))) tfp_dist_a = MultivariateNormalFullCovariance( loc=mean_a, covariance_matrix=covariance_a From 6e05866d9295723738f1c8a7fe74f28c0d61705e Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Sat, 26 Aug 2023 18:34:24 +0100 Subject: [PATCH 57/76] Minimal cola integration. --- docs/examples/constructing_new_kernels.py | 2 +- gpjax/__init__.py | 2 +- gpjax/gaussian_distribution.py | 11 +- gpjax/gps.py | 3 +- gpjax/kernels/computations/base.py | 2 +- gpjax/kernels/computations/basis_functions.py | 9 +- .../kernels/computations/constant_diagonal.py | 14 +- gpjax/kernels/computations/diagonal.py | 12 +- gpjax/kernels/non_euclidean/__init__.py | 2 +- gpjax/kernels/non_euclidean/categorical.py | 12 +- gpjax/likelihoods.py | 3 +- gpjax/linops/__init__.py | 44 --- .../constant_diagonal_linear_operator.py | 202 -------------- gpjax/linops/dense_linear_operator.py | 206 -------------- gpjax/linops/diagonal_linear_operator.py | 239 ---------------- gpjax/linops/identity_linear_operator.py | 133 --------- gpjax/linops/linear_operator.py | 235 ---------------- gpjax/linops/triangular_linear_operator.py | 82 ------ gpjax/linops/utils.py | 129 --------- gpjax/linops/zero_linear_operator.py | 207 -------------- gpjax/lower_cholesky.py | 43 +++ gpjax/objectives.py | 10 +- gpjax/variational_families.py | 15 +- pyproject.toml | 4 +- tests/conftest.py | 8 +- tests/test_kernels/test_computation.py | 22 +- tests/test_linops/__init__.py | 0 .../test_constant_linear_operator.py | 259 ------------------ .../test_linops/test_dense_linear_operator.py | 248 ----------------- .../test_diagonal_linear_operator.py | 253 ----------------- .../test_identity_linear_operator.py | 196 ------------- tests/test_linops/test_linear_operator.py | 156 ----------- .../test_triangular_linear_operator.py | 24 -- tests/test_linops/test_utils.py | 48 ---- .../test_linops/test_zero_linear_operator.py | 216 --------------- tests/test_lower_cholesky.py | 35 +++ 36 files changed, 164 insertions(+), 2922 deletions(-) delete mode 100644 gpjax/linops/__init__.py delete mode 100644 gpjax/linops/constant_diagonal_linear_operator.py delete mode 100644 gpjax/linops/dense_linear_operator.py delete mode 100644 gpjax/linops/diagonal_linear_operator.py delete mode 100644 gpjax/linops/identity_linear_operator.py delete mode 100644 gpjax/linops/linear_operator.py delete mode 100644 gpjax/linops/triangular_linear_operator.py delete mode 100644 gpjax/linops/utils.py delete mode 100644 gpjax/linops/zero_linear_operator.py create mode 100644 gpjax/lower_cholesky.py delete mode 100644 tests/test_linops/__init__.py delete mode 100644 tests/test_linops/test_constant_linear_operator.py delete mode 100644 tests/test_linops/test_dense_linear_operator.py delete mode 100644 tests/test_linops/test_diagonal_linear_operator.py delete mode 100644 tests/test_linops/test_identity_linear_operator.py delete mode 100644 tests/test_linops/test_linear_operator.py delete mode 100644 tests/test_linops/test_triangular_linear_operator.py delete mode 100644 tests/test_linops/test_utils.py delete mode 100644 tests/test_linops/test_zero_linear_operator.py create mode 100644 tests/test_lower_cholesky.py diff --git a/docs/examples/constructing_new_kernels.py b/docs/examples/constructing_new_kernels.py index 0617d1e5b..9355b614f 100644 --- a/docs/examples/constructing_new_kernels.py +++ b/docs/examples/constructing_new_kernels.py @@ -108,7 +108,7 @@ # like our RBF kernel to act on the first, second and fourth dimensions. # %% -slice_kernel = gpx.kernels.RBF(active_dims=[0, 1, 3], lengthscale = jnp.ones((3,))) +slice_kernel = gpx.kernels.RBF(active_dims=[0, 1, 3], lengthscale=jnp.ones((3,))) # %% [markdown] # diff --git a/gpjax/__init__.py b/gpjax/__init__.py index efcce652f..7a5abfedc 100644 --- a/gpjax/__init__.py +++ b/gpjax/__init__.py @@ -29,8 +29,8 @@ RFF, AbstractKernel, BasisFunctionComputation, - ConstantDiagonalKernelComputation, CatKernel, + ConstantDiagonalKernelComputation, DenseKernelComputation, DiagonalKernelComputation, EigenKernelComputation, diff --git a/gpjax/gaussian_distribution.py b/gpjax/gaussian_distribution.py index e8d179f05..131f8955f 100644 --- a/gpjax/gaussian_distribution.py +++ b/gpjax/gaussian_distribution.py @@ -30,6 +30,7 @@ ) import tensorflow_probability.substrates.jax as tfp +from gpjax.lower_cholesky import lower_cholesky from gpjax.typing import ( Array, KeyArray, @@ -55,7 +56,7 @@ def _check_loc_scale(loc: Optional[Any], scale: Optional[Any]) -> None: if scale is not None and not isinstance(scale, cola.LinearOperator): raise ValueError( - f"scale must be a LinearOperator or a JAX array, but got {type(scale)}" + f"The `scale` must be a cola.LinearOperator but got {type(scale)}" ) if scale is not None and (scale.shape[-1] != scale.shape[-2]): @@ -113,7 +114,7 @@ def __init__( scale = Identity(shape=(num_dims, num_dims), dtype=loc.dtype) self.loc = loc - self.scale = scale + self.scale = cola.PSD(scale) def mean(self) -> Float[Array, " N"]: r"""Calculates the mean.""" @@ -196,7 +197,7 @@ def _sample_n(self, key: KeyArray, n: int) -> Float[Array, "n N"]: Float[Array, "n N"]: The samples. """ # Obtain covariance root. - sqrt = cola.sqrt(self.scale) + sqrt = lower_cholesky(self.scale) # Gather n samples from standard normal distribution Z = [z₁, ..., zₙ]ᵀ. Z = jr.normal(key, shape=(n, *self.event_shape)) @@ -264,8 +265,8 @@ def _kl_divergence(q: GaussianDistribution, p: GaussianDistribution) -> ScalarFl sigma_p = p.scale # Find covariance roots. - sqrt_p = cola.sqrt(sigma_p) - sqrt_q = cola.sqrt(sigma_q) + sqrt_p = lower_cholesky(sigma_p) + sqrt_q = lower_cholesky(sigma_q) # diff, μp - μq diff = mu_p - mu_q diff --git a/gpjax/gps.py b/gpjax/gps.py index 99ff6d6ad..e6b9342cf 100644 --- a/gpjax/gps.py +++ b/gpjax/gps.py @@ -50,6 +50,7 @@ Gaussian, NonGaussianLikelihood, ) +from gpjax.lower_cholesky import lower_cholesky from gpjax.mean_functions import AbstractMeanFunction from gpjax.typing import ( Array, @@ -665,7 +666,7 @@ def predict( Kxx = kernel.gram(x) Kxx += cola.ops.I_like(Kxx) * self.prior.jitter Kxx = cola.PSD(Kxx) - Lx = cola.sqrt(Kxx) + Lx = lower_cholesky(Kxx) # Unpack test inputs t = test_inputs diff --git a/gpjax/kernels/computations/base.py b/gpjax/kernels/computations/base.py index d17121cac..2b93a1233 100644 --- a/gpjax/kernels/computations/base.py +++ b/gpjax/kernels/computations/base.py @@ -86,4 +86,4 @@ def diagonal(self, kernel: Kernel, inputs: Num[Array, "N D"]) -> Diagonal: ------- Diagonal: The computed diagonal variance entries. """ - return Diagonal(diag=vmap(lambda x: kernel(x, x))(inputs)) + return PSD(Diagonal(diag=vmap(lambda x: kernel(x, x))(inputs))) diff --git a/gpjax/kernels/computations/basis_functions.py b/gpjax/kernels/computations/basis_functions.py index 7a3cd71fb..e0693f129 100644 --- a/gpjax/kernels/computations/basis_functions.py +++ b/gpjax/kernels/computations/basis_functions.py @@ -10,7 +10,10 @@ Kernel = tp.TypeVar("Kernel", bound="gpjax.kernels.base.AbstractKernel") # noqa: F821 from cola import PSD -from cola.ops import Dense +from cola.ops import ( + Dense, + LinearOperator, +) # TODO: Use low rank linear operator! @@ -38,7 +41,7 @@ def cross_covariance( z2 = self.compute_features(kernel, y) return self.scaling(kernel) * jnp.matmul(z1, z2.T) - def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Dense: + def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> LinearOperator: r"""Compute an approximate Gram matrix. For the Gram matrix, we can save computations by computing only one matrix @@ -49,7 +52,7 @@ def gram(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Dense: inputs (Float[Array, "N D"]): A $`N x D`$ array of inputs. Returns: - Dense: A dense linear operator representing the + LinearOperator: A dense linear operator representing the $`N \times N`$ Gram matrix. """ z1 = self.compute_features(kernel, inputs) diff --git a/gpjax/kernels/computations/constant_diagonal.py b/gpjax/kernels/computations/constant_diagonal.py index 7748154df..c7dd8639e 100644 --- a/gpjax/kernels/computations/constant_diagonal.py +++ b/gpjax/kernels/computations/constant_diagonal.py @@ -15,9 +15,11 @@ import typing as tp +from cola import PSD from cola.ops import ( Diagonal, Identity, + LinearOperator, ) from jax import vmap import jax.numpy as jnp @@ -30,20 +32,24 @@ class ConstantDiagonalKernelComputation(AbstractKernelComputation): - def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> Diagonal: + def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> LinearOperator: r"""Compute the Gram matrix. Compute Gram covariance operator of the kernel function. Args: kernel (Kernel): the kernel function. - x (Float[Array, "N N"]): The inputs to the kernel function. + x (Float[Array, "N D"]): The inputs to the kernel function. + + Returns + ------- + LinearOperator: Gram covariance operator of the kernel function. """ value = kernel(x[0], x[0]) dtype = value.dtype shape = (x.shape[0], x.shape[0]) - return jnp.atleast_1d(value) * Identity(shape=shape, dtype=dtype) + return PSD(jnp.atleast_1d(value) * Identity(shape=shape, dtype=dtype)) def diagonal(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Diagonal: r"""Compute the diagonal Gram matrix's entries. @@ -61,7 +67,7 @@ def diagonal(self, kernel: Kernel, inputs: Float[Array, "N D"]) -> Diagonal: """ diag = vmap(lambda x: kernel(x, x))(inputs) - return Diagonal(diag=diag) + return PSD(Diagonal(diag=diag)) def cross_covariance( self, kernel: Kernel, x: Float[Array, "N D"], y: Float[Array, "M D"] diff --git a/gpjax/kernels/computations/diagonal.py b/gpjax/kernels/computations/diagonal.py index 266ca4165..d4c323da8 100644 --- a/gpjax/kernels/computations/diagonal.py +++ b/gpjax/kernels/computations/diagonal.py @@ -14,7 +14,11 @@ # ============================================================================== import beartype.typing as tp -from cola.ops import Diagonal +from cola import PSD +from cola.ops import ( + Diagonal, + LinearOperator, +) from jax import vmap from jaxtyping import Float @@ -29,7 +33,7 @@ class DiagonalKernelComputation(AbstractKernelComputation): a diagonal Gram matrix. """ - def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> Diagonal: + def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> LinearOperator: r"""Compute the Gram matrix. For a kernel with diagonal structure, compute the $`N\times N`$ Gram matrix on @@ -41,9 +45,9 @@ def gram(self, kernel: Kernel, x: Float[Array, "N D"]) -> Diagonal: Returns ------- - Diagonal: The computed square Gram matrix. + LinearOperator: The computed square Gram matrix. """ - return Diagonal(diag=vmap(lambda x: kernel(x, x))(x)) + return PSD(Diagonal(diag=vmap(lambda x: kernel(x, x))(x))) def cross_covariance( self, kernel: Kernel, x: Float[Array, "N D"], y: Float[Array, "M D"] diff --git a/gpjax/kernels/non_euclidean/__init__.py b/gpjax/kernels/non_euclidean/__init__.py index 1289f1d60..ee45287b0 100644 --- a/gpjax/kernels/non_euclidean/__init__.py +++ b/gpjax/kernels/non_euclidean/__init__.py @@ -13,7 +13,7 @@ # limitations under the License. # ============================================================================== -from gpjax.kernels.non_euclidean.graph import GraphKernel from gpjax.kernels.non_euclidean.categorical import CatKernel +from gpjax.kernels.non_euclidean.graph import GraphKernel __all__ = ["GraphKernel", "CatKernel"] diff --git a/gpjax/kernels/non_euclidean/categorical.py b/gpjax/kernels/non_euclidean/categorical.py index e0f1e610b..1d376956f 100644 --- a/gpjax/kernels/non_euclidean/categorical.py +++ b/gpjax/kernels/non_euclidean/categorical.py @@ -15,9 +15,16 @@ from dataclasses import dataclass -from typing import NamedTuple, Union +from typing import ( + NamedTuple, + Union, +) + import jax.numpy as jnp -from jaxtyping import Float, Int +from jaxtyping import ( + Float, + Int, +) import tensorflow_probability.substrates.jax as tfp from gpjax.base import ( @@ -25,7 +32,6 @@ static_field, ) from gpjax.kernels.base import AbstractKernel - from gpjax.typing import ( Array, ScalarInt, diff --git a/gpjax/likelihoods.py b/gpjax/likelihoods.py index a926957b1..ed388a391 100644 --- a/gpjax/likelihoods.py +++ b/gpjax/likelihoods.py @@ -35,7 +35,6 @@ AnalyticalGaussianIntegrator, GHQuadratureIntegrator, ) -from gpjax.linops.utils import to_dense from gpjax.typing import ( Array, ScalarFloat, @@ -160,7 +159,7 @@ def predict( tfd.Distribution: The predictive distribution. """ n_data = dist.event_shape[0] - cov = to_dense(dist.covariance()) + cov = dist.covariance() noisy_cov = cov.at[jnp.diag_indices(n_data)].add(self.obs_noise) return tfd.MultivariateNormalFullCovariance(dist.mean(), noisy_cov) diff --git a/gpjax/linops/__init__.py b/gpjax/linops/__init__.py deleted file mode 100644 index 8ee71691c..000000000 --- a/gpjax/linops/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - -from gpjax.linops.constant_diagonal_linear_operator import ( - ConstantDiagonalLinearOperator, -) -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.identity_linear_operator import IdentityLinearOperator -from gpjax.linops.linear_operator import LinearOperator -from gpjax.linops.triangular_linear_operator import ( - LowerTriangularLinearOperator, - UpperTriangularLinearOperator, -) -from gpjax.linops.utils import ( - identity, - to_dense, -) -from gpjax.linops.zero_linear_operator import ZeroLinearOperator - -__all__ = [ - "LinearOperator", - "DenseLinearOperator", - "DiagonalLinearOperator", - "ConstantDiagonalLinearOperator", - "IdentityLinearOperator", - "ZeroLinearOperator", - "LowerTriangularLinearOperator", - "UpperTriangularLinearOperator", - "identity", - "to_dense", -] diff --git a/gpjax/linops/constant_diagonal_linear_operator.py b/gpjax/linops/constant_diagonal_linear_operator.py deleted file mode 100644 index d3c58b192..000000000 --- a/gpjax/linops/constant_diagonal_linear_operator.py +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import dataclass - -from beartype.typing import ( - Any, - Union, -) -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.base import static_field -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.linear_operator import LinearOperator -from gpjax.typing import ( - Array, - ScalarFloat, -) - - -def _check_args(value: Any, size: Any) -> None: - if not isinstance(size, int): - raise ValueError(f"`length` must be an integer, but `length = {size}`.") - - if value.ndim != 1: - raise ValueError( - "`value` must be one dimensional scalar, but `value.shape =" - f" {value.shape}`." - ) - - -@dataclass -class ConstantDiagonalLinearOperator(DiagonalLinearOperator): - value: Float[Array, "1"] - size: int = static_field() - - def __init__( - self, value: Float[Array, "1"], size: int, dtype: jnp.dtype = None - ) -> None: - """Initialize the constant diagonal linear operator. - - Args: - value (Float[Array, "1"]): Constant value of the diagonal. - size (int): Size of the diagonal. - """ - _check_args(value, size) - - if dtype is not None: - value = value.astype(dtype) - - self.value = value - self.size = size - self.shape = (size, size) - self.dtype = value.dtype - - def __add__( - self, other: Union[Float[Array, "N N"], LinearOperator] - ) -> LinearOperator: - if isinstance(other, ConstantDiagonalLinearOperator): - if other.size == self.size: - return ConstantDiagonalLinearOperator( - value=self.value + other.value, size=self.size - ) - - raise ValueError( - f"`length` must be the same, but `length = {self.size}` and `length =" - f" {other.size}`." - ) - - else: - return super().__add__(other) - - def __mul__(self, other: Union[ScalarFloat, Float[Array, "1"]]) -> LinearOperator: - """Multiply covariance operator by scalar. - - Args: - other (LinearOperator): Scalar. - - Returns - ------- - LinearOperator: Covariance operator multiplied by a scalar. - """ - return ConstantDiagonalLinearOperator(value=self.value * other, size=self.size) - - def _add_diagonal(self, other: DiagonalLinearOperator) -> LinearOperator: - """Add diagonal to the covariance operator, useful for computing, Kxx + Io². - - Args: - other (DiagonalLinearOperator): Diagonal covariance operator to add to the covariance operator. - - Returns - ------- - LinearOperator: Covariance operator with the diagonal added. - """ - if isinstance(other, ConstantDiagonalLinearOperator): - if other.size == self.size: - return ConstantDiagonalLinearOperator( - value=self.value + other.value, size=self.size - ) - - raise ValueError( - f"`length` must be the same, but `length = {self.size}` and `length =" - f" {other.size}`." - ) - - else: - return super()._add_diagonal(other) - - def diagonal(self) -> Float[Array, " N"]: - """Diagonal of the covariance operator.""" - return self.value * jnp.ones(self.size) - - def to_root(self) -> "ConstantDiagonalLinearOperator": - """ - Lower triangular. - - Returns - ------- - Float[Array, "N N"]: Lower triangular matrix. - """ - return ConstantDiagonalLinearOperator( - value=jnp.sqrt(self.value), size=self.size - ) - - def log_det(self) -> ScalarFloat: - """Log determinant. - - Returns - ------- - ScalarFloat: Log determinant of the covariance matrix. - """ - return 2.0 * self.size * jnp.log(self.value.squeeze()) - - def inverse(self) -> "ConstantDiagonalLinearOperator": - """Inverse of the covariance operator. - - Returns - ------- - DiagonalLinearOperator: Inverse of the covariance operator. - """ - return ConstantDiagonalLinearOperator(value=1.0 / self.value, size=self.size) - - def solve(self, rhs: Float[Array, "... M"]) -> Float[Array, "... M"]: - """Solve linear system. - - Args: - rhs (Float[Array, "N M"]): Right hand side of the linear system. - - Returns - ------- - Float[Array, "N M"]: Solution of the linear system. - """ - return rhs / self.value - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "ConstantDiagonalLinearOperator": - """Construct covariance operator from dense matrix. - - Args: - dense (Float[Array, "N N"]): Dense matrix. - - Returns - ------- - DiagonalLinearOperator: Covariance operator. - """ - return ConstantDiagonalLinearOperator( - value=jnp.atleast_1d(dense[0, 0]), size=dense.shape[0] - ) - - @classmethod - def from_root( - cls, root: "ConstantDiagonalLinearOperator" - ) -> "ConstantDiagonalLinearOperator": - """Construct covariance operator from root. - - Args: - root (ConstantDiagonalLinearOperator): Root of the covariance operator. - - Returns - ------- - ConstantDiagonalLinearOperator: Covariance operator. - """ - return ConstantDiagonalLinearOperator(value=root.value**2, size=root.size) - - -__all__ = [ - "ConstantDiagonalLinearOperator", -] diff --git a/gpjax/linops/dense_linear_operator.py b/gpjax/linops/dense_linear_operator.py deleted file mode 100644 index ad98ee9f8..000000000 --- a/gpjax/linops/dense_linear_operator.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import dataclass - -from beartype.typing import Union -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.linops.linear_operator import LinearOperator -from gpjax.linops.utils import to_linear_operator -from gpjax.typing import ( - Array, - ScalarFloat, - VecNOrMatNM, -) - - -def _check_matrix(matrix: Array) -> None: - if matrix.ndim != 2: - raise ValueError( - "The `matrix` must have at two dimensions, but " - f"`scale.shape = {matrix.shape}`." - ) - - if matrix.shape[-1] != matrix.shape[-2]: - raise ValueError( - f"The `matrix` must be a square matrix, but `scale.shape = {matrix.shape}`." - ) - - -@dataclass -class DenseLinearOperator(LinearOperator): - """Dense covariance operator.""" - - matrix: Float[Array, "N N"] - - def __init__( - self, matrix: Float[Array, "N N"], dtype: jnp.dtype = None, shape: tuple = None - ) -> None: - """Initialize the covariance operator. - - Args: - matrix (Float[Array, "N N"]): Dense matrix. - """ - _check_matrix(matrix) - - if dtype is not None: - matrix = matrix.astype(dtype) - - self.matrix = matrix - self.shape = matrix.shape - self.dtype = matrix.dtype - - def __add__( - self, other: Union[LinearOperator, Float[Array, "N N"]] - ) -> LinearOperator: - """Add diagonal to another linear operator. - - Args: - other (Union[LinearOperator, Float[Array, "N N"]]): Other linear operator. Dimension of both operators must match. If the other linear operator is not a DiagonalLinearOperator, dense matrix addition is used. - - Returns - ------- - LinearOperator: linear operator plus the diagonal linear operator. - """ - from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator - from gpjax.linops.zero_linear_operator import ZeroLinearOperator - - other = to_linear_operator(other) - - if isinstance(other, DiagonalLinearOperator): - return self._add_diagonal(other) - - elif isinstance(other, DenseLinearOperator): - return DenseLinearOperator(matrix=self.matrix + other.matrix) - - elif isinstance(other, ZeroLinearOperator): - return self - - else: - raise NotImplementedError - - def __mul__(self, other: ScalarFloat) -> LinearOperator: - """Multiply covariance operator by scalar. - - Args: - other (LinearOperator): Scalar. - - Returns - ------- - LinearOperator: Covariance operator multiplied by a scalar. - """ - return DenseLinearOperator(matrix=self.matrix * other) - - def _add_diagonal( - self, - other: "gpjax.linops.diagonal_linear_operator.DiagonalLinearOperator", # noqa: F821 - ) -> LinearOperator: - """Add diagonal to the covariance operator, useful for computing, Kxx + Io². - - Args: - other (DiagonalLinearOperator): Diagonal covariance operator to add to the covariance operator. - - Returns - ------- - LinearOperator: Sum of the two covariance operators. - """ - dim = self.shape[0] - diag_indices = jnp.diag_indices(dim) - new_matrix = self.matrix.at[diag_indices].add(other.diagonal()) - - return DenseLinearOperator(matrix=new_matrix) - - def diagonal(self) -> Float[Array, " N"]: - """ - Diagonal of the covariance operator. - - Returns - ------- - Float[Array, " N"]: The diagonal of the covariance operator. - """ - return jnp.diag(self.matrix) - - def __matmul__(self, other: VecNOrMatNM) -> VecNOrMatNM: - """Matrix multiplication. - - Args: - other (Float[Array, "N M"]): Matrix to multiply with. - - Returns - ------- - Float[Array, "N M"]: Result of matrix multiplication. - """ - return jnp.matmul(self.matrix, other) - - def to_dense(self) -> Float[Array, "N N"]: - """Construct dense Covariance matrix from the covariance operator. - - Returns - ------- - Float[Array, "N N"]: Dense covariance matrix. - """ - return self.matrix - - @classmethod - def from_dense(cls, matrix: Float[Array, "N N"]) -> "DenseLinearOperator": - """Construct covariance operator from dense covariance matrix. - - Args: - matrix (Float[Array, "N N"]): Dense covariance matrix. - - Returns - ------- - DenseLinearOperator: Covariance operator. - """ - return DenseLinearOperator(matrix=matrix) - - @classmethod - def from_root(cls, root: LinearOperator) -> "DenseLinearOperator": - """Construct covariance operator from the root of the covariance matrix. - - Args: - root (Float[Array, "N N"]): Root of the covariance matrix. - - Returns - ------- - DenseLinearOperator: Covariance operator. - """ - return DenseFromRootLinearOperator(root=root) - - -class DenseFromRootLinearOperator(DenseLinearOperator): - root: LinearOperator - - def __init__(self, root: LinearOperator): - """Initialize the covariance operator.""" - self.root = root - self.shape = root.shape - self.dtype = root.dtype - - def to_root(self) -> LinearOperator: - return self.root - - @property - def matrix(self) -> Float[Array, "N N"]: - dense_root = self.root.to_dense() - return dense_root @ dense_root.T - - -__all__ = [ - "DenseLinearOperator", -] diff --git a/gpjax/linops/diagonal_linear_operator.py b/gpjax/linops/diagonal_linear_operator.py deleted file mode 100644 index 3453d5734..000000000 --- a/gpjax/linops/diagonal_linear_operator.py +++ /dev/null @@ -1,239 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import dataclass - -from beartype.typing import ( - Any, - Union, -) -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.linear_operator import LinearOperator -from gpjax.linops.utils import to_linear_operator -from gpjax.typing import ( - Array, - ScalarFloat, - VecNOrMatNM, -) - - -def _check_diag(diag: Any) -> None: - """Check if the diagonal is a vector.""" - if diag.ndim != 1: - raise ValueError( - "The `matrix` must be a one dimension vector, but " - f"`diag.shape = {diag.shape}`." - ) - - -@dataclass -class DiagonalLinearOperator(LinearOperator): - """Diagonal covariance operator.""" - - diag: Float[Array, " N"] - - def __init__(self, diag: Float[Array, " N"], dtype: jnp.dtype = None) -> None: - """Initialize the covariance operator. - - Args: - diag (Float[Array, " N"]): Diagonal of the covariance operator. - """ - _check_diag(diag) - - if dtype is not None: - diag = diag.astype(dtype) - - dim = diag.shape[0] - self.diag = diag - self.shape = (dim, dim) - self.dtype = diag.dtype - - def diagonal(self) -> Float[Array, " N"]: - """Diagonal of the covariance operator. - - Returns - ------- - Float[Array, " N"]: Diagonal of the covariance operator. - """ - return self.diag - - def __add__( - self, other: Union[LinearOperator, Float[Array, "N N"]] - ) -> LinearOperator: - """Add diagonal to another linear operator. - - Args: - other (Union[LinearOperator, Float[Array, "N N"]]): Other linear operator. Dimension of both operators must match. If the other linear operator is not a DiagonalLinearOperator, dense matrix addition is used. - - Returns - ------- - LinearOperator: linear operator plus the diagonal linear operator. - """ - from gpjax.linops.zero_linear_operator import ZeroLinearOperator - - other = to_linear_operator(other) - - if isinstance(other, DiagonalLinearOperator): - return DiagonalLinearOperator(diag=self.diagonal() + other.diagonal()) - - elif isinstance(other, DenseLinearOperator): - return other._add_diagonal(self) - - elif isinstance(other, ZeroLinearOperator): - return self - - else: - raise NotImplementedError - - def __mul__(self, other: ScalarFloat) -> LinearOperator: - """Multiply covariance operator by scalar. - - Args: - other (LinearOperator): Scalar. - - Returns - ------- - LinearOperator: Covariance operator multiplied by a scalar. - """ - return DiagonalLinearOperator(diag=self.diagonal() * other) - - def _add_diagonal(self, other: "DiagonalLinearOperator") -> LinearOperator: - """Add diagonal to the covariance operator, useful for computing, Kxx + Io². - - Args: - other (DiagonalLinearOperator): Diagonal covariance operator to add to the covariance operator. - - Returns - ------- - LinearOperator: Covariance operator with the diagonal added. - """ - return DiagonalLinearOperator(diag=self.diagonal() + other.diagonal()) - - def to_dense(self) -> Float[Array, "N N"]: - """Construct dense Covariance matrix from the covariance operator. - - Returns - ------- - Float[Array, "N N"]: Dense covariance matrix. - """ - return jnp.diag(self.diagonal()) - - def __matmul__(self, other: VecNOrMatNM) -> VecNOrMatNM: - """Matrix multiplication. - - Args: - other (Float[Array, "N M"]): Matrix to multiply with. - - Returns - ------- - Float[Array, "N M"]: Result of matrix multiplication. - """ - diag = ( - self.diagonal() if other.ndim == 1 else jnp.expand_dims(self.diagonal(), -1) - ) - - return diag * other - - def to_root(self) -> "DiagonalLinearOperator": - """ - Lower triangular. - - Returns - ------- - Float[Array, "N N"]: Lower triangular matrix. - """ - return DiagonalLinearOperator(diag=jnp.sqrt(self.diagonal())) - - def log_det(self) -> ScalarFloat: - """Log determinant. - - Returns - ------- - ScalarFloat: Log determinant of the covariance matrix. - """ - return jnp.sum(jnp.log(self.diagonal())) - - def inverse(self) -> "DiagonalLinearOperator": - """Inverse of the covariance operator. - - Returns - ------- - DiagonalLinearOperator: Inverse of the covariance operator. - """ - return DiagonalLinearOperator(diag=1.0 / self.diagonal()) - - def solve(self, rhs: VecNOrMatNM) -> VecNOrMatNM: - """Solve linear system. - - Args: - rhs (Float[Array, "N M"]): Right hand side of the linear system. - - Returns - ------- - Float[Array, "N M"]: Solution of the linear system. - """ - return self.inverse() @ rhs - - @classmethod - def from_root(cls, root: "DiagonalLinearOperator") -> "DiagonalLinearOperator": - """Construct covariance operator from the lower triangular matrix. - - Returns - ------- - DiagonalLinearOperator: Covariance operator. - """ - return DiagonalFromRootLinearOperator(root=root) - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "DiagonalLinearOperator": - """Construct covariance operator from its dense matrix representation. - - Returns - ------- - DiagonalLinearOperator: Covariance operator. - """ - return DiagonalLinearOperator(diag=dense.diagonal()) - - -class DiagonalFromRootLinearOperator(DiagonalLinearOperator): - root: DiagonalLinearOperator - - def __init__(self, root: DiagonalLinearOperator): - """Initialize the covariance operator.""" - if not isinstance(root, DiagonalLinearOperator): - raise ValueError("root must be a DiagonalLinearOperator") - - self.root = root - self.shape = root.shape - self.dtype = root.dtype - - def to_root(self) -> LinearOperator: - return self.root - - @property - def diag(self) -> Float[Array, " N"]: - return self.root.diagonal() ** 2 - - def diagonal(self) -> Float[Array, " N"]: - return self.root.diagonal() ** 2 - - -__all__ = [ - "DiagonalLinearOperator", -] diff --git a/gpjax/linops/identity_linear_operator.py b/gpjax/linops/identity_linear_operator.py deleted file mode 100644 index 9b5bfbeda..000000000 --- a/gpjax/linops/identity_linear_operator.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import dataclass - -from beartype.typing import Any -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.linops.constant_diagonal_linear_operator import ( - ConstantDiagonalLinearOperator, -) -from gpjax.linops.utils import default_dtype -from gpjax.typing import ( - Array, - ScalarFloat, -) - - -def _check_size(size: Any) -> None: - """Check that size is an integer.""" - if not isinstance(size, int): - raise ValueError(f"`size` must be an integer, but `size = {size}`.") - - -@dataclass -class IdentityLinearOperator(ConstantDiagonalLinearOperator): - """Identity linear operator.""" - - def __init__(self, size: int, dtype: jnp.dtype = None) -> None: - """Identity matrix. - - Args: - size (int): Size of the identity matrix. - """ - _check_size(size) - - if dtype is None: - dtype = default_dtype() - - self.value = jnp.array([1.0], dtype=dtype) - self.size = size - self.shape = (size, size) - self.dtype = dtype - - def __matmul__(self, other: Float[Array, "N M"]) -> Float[Array, "N M"]: - """Matrix multiplication. - - Args: - other (Float[Array, "N M"]): Matrix to multiply with. - - Returns - ------- - Float[Array, "N M"]: Result of matrix multiplication. - """ - return other - - def to_root(self) -> "IdentityLinearOperator": - """ - Lower triangular. - - Returns - ------- - Float[Array, "N N"]: Lower triangular matrix. - """ - return self - - def log_det(self) -> ScalarFloat: - """Log determinant. - - Returns - ------- - ScalarFloat: Log determinant of the covariance matrix. - """ - return jnp.array(0.0) - - def inverse(self) -> "IdentityLinearOperator": - """Inverse of the covariance operator. - - Returns - ------- - DiagonalLinearOperator: Inverse of the covariance operator. - """ - return self - - def solve(self, rhs: Float[Array, "... M"]) -> Float[Array, "... M"]: - """Solve linear system. - - Args: - rhs (Float[Array, "N M"]): Right hand side of the linear system. - - Returns - ------- - Float[Array, "N M"]: Solution of the linear system. - """ - # TODO: Check shapes. - - return rhs - - @classmethod - def from_root(cls, root: "IdentityLinearOperator") -> "IdentityLinearOperator": - """Construct from root. - - Args: - root (IdentityLinearOperator): Root of the covariance operator. - - Returns - ------- - IdentityLinearOperator: Covariance operator. - """ - return root - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "IdentityLinearOperator": - return IdentityLinearOperator(dense.shape[0]) - - -__all__ = [ - "IdentityLinearOperator", -] diff --git a/gpjax/linops/linear_operator.py b/gpjax/linops/linear_operator.py deleted file mode 100644 index efef78d9b..000000000 --- a/gpjax/linops/linear_operator.py +++ /dev/null @@ -1,235 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -import abc -from dataclasses import dataclass - -from beartype.typing import ( - Any, - Generic, - Iterable, - Mapping, - Tuple, - Type, - TypeVar, - Union, -) -import jax.numpy as jnp -from jaxtyping import Float -from simple_pytree import ( - Pytree, - static_field, -) - -from gpjax.typing import ( - Array, - ScalarFloat, -) - -# Generic type. -T = TypeVar("T") - -# Generic nested type. -NestedT = Union[T, Iterable["NestedT"], Mapping[Any, "NestedT"]] - -# Nested types. -DTypes = Union[Type[jnp.float32], Type[jnp.float64], Type[jnp.int32], Type[jnp.int64]] -ShapeT = TypeVar("ShapeT", bound=NestedT[Tuple[int, ...]]) -DTypeT = TypeVar("DTypeT", bound=NestedT[DTypes]) - -# The Generic type is used for type checking the LinearOperator's shape and datatype. -# `static_field` is used to mark nodes of the PyTree that don't change under JAX transformations. -# this is important, so that we e.g., don't take the gradient with respect to the shape! - - -@dataclass -class LinearOperator(Pytree, Generic[ShapeT, DTypeT]): - """Linear operator base class.""" - - shape: ShapeT = static_field() - dtype: DTypeT = static_field() - - def __repr__(self) -> str: - """Linear operator representation.""" - return f"{type(self).__name__}(shape={self.shape}, dtype={self.dtype.__name__})" - - @property - def ndim(self) -> int: - """Linear operator dimension.""" - return len(self.shape) - - @property - def T(self) -> "LinearOperator": - """Transpose linear operator. Currently, we assume all linear operators are square and symmetric.""" - return self - - def __sub__( - self, other: Union["LinearOperator", Float[Array, "N N"]] - ) -> "LinearOperator": - """Subtract linear operator.""" - return self + (other * -1) - - def __rsub__( - self, other: Union["LinearOperator", Float[Array, "N N"]] - ) -> "LinearOperator": - """Reimplimentation of subtract linear operator.""" - return (self * -1) + other - - def __add__( - self, other: Union["LinearOperator", Float[Array, "N N"]] - ) -> "LinearOperator": - """Add linear operator.""" - raise NotImplementedError - - def __radd__( - self, other: Union["LinearOperator", Float[Array, "N N"]] - ) -> "LinearOperator": - """Reimplimentation of add linear operator.""" - return self + other - - @abc.abstractmethod - def __mul__(self, other: ScalarFloat) -> "LinearOperator": - """Multiply linear operator by scalar.""" - raise NotImplementedError - - def __rmul__(self, other: ScalarFloat) -> "LinearOperator": - """Reimplimentation of multiply linear operator by scalar.""" - return self.__mul__(other) - - @abc.abstractmethod - def _add_diagonal( - self, - other: "gpjax.linops.diagonal_linear_operator.DiagonalLinearOperator", # noqa: F821 - ) -> "LinearOperator": - """Add diagonal linear operator to a linear operator, useful e.g., for adding jitter.""" - return NotImplementedError - - @abc.abstractmethod - def __matmul__( - self, other: Union["LinearOperator", Float[Array, "N M"]] - ) -> Union["LinearOperator", Float[Array, "N M"]]: - """Matrix multiplication.""" - raise NotImplementedError - - def __rmatmul__( - self, other: Union["LinearOperator", Float[Array, "N M"]] - ) -> Union["LinearOperator", Float[Array, "N M"]]: - """Reimplimentation of matrix multiplication.""" - # Exploit the fact that linear operators are square and symmetric. - if other.ndim == 1: - return self.T @ other - return (self.T @ other.T).T - - @abc.abstractmethod - def diagonal(self) -> Float[Array, " N"]: - """Diagonal of the linear operator. - - Returns - ------- - Float[Array, " N"]: Diagonal of the linear operator. - """ - raise NotImplementedError - - def trace(self) -> ScalarFloat: - """Trace of the linear matrix. - - Returns - ------- - ScalarFloat: Trace of the linear matrix. - """ - return jnp.sum(self.diagonal()) - - def log_det(self) -> ScalarFloat: - """Log determinant of the linear matrix. Default implementation uses dense Cholesky decomposition. - - Returns - ------- - ScalarFloat: Log determinant of the linear matrix. - """ - root = self.to_root() - - return 2.0 * jnp.sum(jnp.log(root.diagonal())) - - def to_root(self) -> "LinearOperator": - """Compute the root of the linear operator via the Cholesky decomposition. - - Returns - ------- - Float[Array, "N N"]: Lower Cholesky decomposition of the linear operator. - """ - from gpjax.linops.triangular_linear_operator import ( - LowerTriangularLinearOperator, - ) - - L = jnp.linalg.cholesky(self.to_dense()) - - return LowerTriangularLinearOperator.from_dense(L) - - def inverse(self) -> "LinearOperator": - """Inverse of the linear matrix. Default implementation uses dense Cholesky decomposition. - - Returns - ------- - LinearOperator: Inverse of the linear matrix. - """ - from gpjax.linops.dense_linear_operator import DenseLinearOperator - - n = self.shape[0] - - return DenseLinearOperator(self.solve(jnp.eye(n))) - - def solve(self, rhs: Float[Array, "... M"]) -> Float[Array, "... M"]: - """Solve linear system. Default implementation uses dense Cholesky decomposition. - - Args: - rhs (Float[Array, "N M"]): Right hand side of the linear system. - - Returns - ------- - Float[Array, "N M"]: Solution of the linear system. - """ - root = self.to_root() - rootT = root.T - - return rootT.solve(root.solve(rhs)) - - @abc.abstractmethod - def to_dense(self) -> Float[Array, "N N"]: - """Construct dense matrix from the linear operator. - - Returns - ------- - Float[Array, "N N"]: Dense linear matrix. - """ - raise NotImplementedError - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "LinearOperator": - """Construct linear operator from dense matrix. - - Args: - dense (Float[Array, "N N"]): Dense matrix. - - Returns - ------- - LinearOperator: Linear operator. - """ - raise NotImplementedError - - -__all__ = [ - "LinearOperator", -] diff --git a/gpjax/linops/triangular_linear_operator.py b/gpjax/linops/triangular_linear_operator.py deleted file mode 100644 index c2c85c294..000000000 --- a/gpjax/linops/triangular_linear_operator.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -import jax.numpy as jnp -import jax.scipy as jsp -from jaxtyping import Float - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.linear_operator import LinearOperator -from gpjax.typing import Array - - -class LowerTriangularLinearOperator(DenseLinearOperator): - """Current implementation of the following methods is inefficient. - We assume a dense matrix representation of the operator. But take advantage of the solve structure. - """ - - @property - def T(self) -> "UpperTriangularLinearOperator": - return UpperTriangularLinearOperator(matrix=self.matrix.T) - - def to_root(self) -> LinearOperator: - raise ValueError("Matrix is not positive semi-definite.") - - def inverse(self) -> DenseLinearOperator: - matrix = self.solve(jnp.eye(self.size)) - return DenseLinearOperator(matrix) - - def solve(self, rhs: Float[Array, "... M"]) -> Float[Array, "... M"]: - return jsp.linalg.solve_triangular(self.to_dense(), rhs, lower=True) - - @classmethod - def from_root(cls, root: LinearOperator) -> None: - raise ValueError("LowerTriangularLinearOperator does not have a root.") - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "LowerTriangularLinearOperator": - return LowerTriangularLinearOperator(matrix=dense) - - -class UpperTriangularLinearOperator(DenseLinearOperator): - """Current implementation of the following methods is inefficient. - We assume a dense matrix representation of the operator. But take advantage of the solve structure. - """ - - @property - def T(self) -> LowerTriangularLinearOperator: - return LowerTriangularLinearOperator(matrix=self.matrix.T) - - def to_root(self) -> LinearOperator: - raise ValueError("Matrix is not positive semi-definite.") - - def inverse(self) -> DenseLinearOperator: - matrix = self.solve(jnp.eye(self.size)) - return DenseLinearOperator(matrix) - - def solve(self, rhs: Float[Array, "... M"]) -> Float[Array, "... M"]: - return jsp.linalg.solve_triangular(self.to_dense(), rhs, lower=False) - - @classmethod - def from_root(cls, root: LinearOperator) -> None: - raise ValueError("LowerTriangularLinearOperator does not have a root.") - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "UpperTriangularLinearOperator": - return UpperTriangularLinearOperator(matrix=dense) - - -__all__ = ["LowerTriangularLinearOperator", "UpperTriangularLinearOperator"] diff --git a/gpjax/linops/utils.py b/gpjax/linops/utils.py deleted file mode 100644 index e2bdad7ff..000000000 --- a/gpjax/linops/utils.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from beartype.typing import ( - Tuple, - Type, - Union, -) -import jax -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.linops.linear_operator import LinearOperator -from gpjax.typing import Array - - -def identity( - n: int, -) -> "gpjax.linops.identity_linear_operator.IdentityLinearOperator": # noqa: F821 - """Identity matrix. - - Args: - n (int): Size of the identity matrix. - - Returns - ------- - IdentityLinearOperator: Identity matrix of shape [n, n]. - """ - from gpjax.linops.identity_linear_operator import IdentityLinearOperator - - return IdentityLinearOperator(size=n) - - -def to_dense(obj: Union[Float[Array, "..."], LinearOperator]): - """ - Ensure an object is a dense matrix. - - Args: - obj (Union[Float[Array, "..."], LinearOperator]): Linear operator to convert. - - Returns - ------- - Float[Array, "..."]: Dense matrix. - """ - if isinstance(obj, jnp.ndarray): - return obj - elif isinstance(obj, LinearOperator): - return obj.to_dense() - else: - raise TypeError( - "object of class {} cannot be made into a Tensor".format( - obj.__class__.__name__ - ) - ) - - -def to_linear_operator(obj: Union[Float[Array, "..."], LinearOperator]): - """ - Ensure an object is a linear operator. - - Args: - obj (Union[Float[Array, "..."], LinearOperator]): Linear operator to convert. - - Returns - ------- - LinearOperator: Linear operator. - """ - if isinstance(obj, LinearOperator): - return obj - - elif isinstance(obj, jnp.ndarray): - from gpjax.linops.dense_linear_operator import DenseLinearOperator - - return DenseLinearOperator.from_dense(obj) - else: - raise TypeError( - "object of class {} cannot be made into a Tensor".format( - obj.__class__.__name__ - ) - ) - - -def check_shapes_match(shape1: Tuple[int, ...], shape2: Tuple[int, ...]) -> None: - """Check shapes of two objects. - - Args: - shape1 (Tuple[int, "..."]): Shape of the first object. - shape2 (Tuple[int, "..."]): Shape of the second object. - - Raises - ------ - ValueError: Shapes of the two objects do not match. - """ - if shape1 != shape2: - raise ValueError( - f"`shape1` must have shape {shape1}, but `shape2` has shape {shape2}." - ) - - -def default_dtype() -> Union[Type[jnp.float64], Type[jnp.float32]]: - """Get the default dtype for the linear operator. - - Returns - ------- - jnp.dtype: Default dtype for the linear operator. - """ - if jax.config.x64_enabled: - return jnp.float64 - else: - return jnp.float32 - - -__all__ = [ - "identity", - "to_dense", -] diff --git a/gpjax/linops/zero_linear_operator.py b/gpjax/linops/zero_linear_operator.py deleted file mode 100644 index 34c86d7db..000000000 --- a/gpjax/linops/zero_linear_operator.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import dataclass - -from beartype.typing import ( - Any, - Tuple, - Union, -) -import jax.numpy as jnp -from jaxtyping import Float - -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.linear_operator import LinearOperator -from gpjax.linops.utils import ( - check_shapes_match, - default_dtype, - to_linear_operator, -) -from gpjax.typing import ( - Array, - ScalarFloat, -) - - -def _check_size(shape: Any) -> None: - if not isinstance(shape, tuple): - raise ValueError( - f"`shape` must be a a tuple, but `type(shape) = {type(shape)}`." - ) - - if len(shape) != 2: - raise ValueError(f"`shape` must be a 2-tuple, but `shape = {shape}`.") - - -# TODO: Generalise to non-square matrices. -@dataclass -class ZeroLinearOperator(LinearOperator): - """Zero linear operator.""" - - def __init__(self, shape: Tuple[int, ...], dtype: jnp.dtype = None) -> None: - _check_size(shape) - - if dtype is None: - dtype = default_dtype() - - self.shape = shape - self.dtype = dtype - - def diagonal(self) -> Float[Array, " N"]: - """ - Diagonal of the covariance operator. - - Returns - ------- - Float[Array, " N"]: The diagonal of the covariance operator. - """ - return jnp.zeros(self.shape[0]) - - def __add__( - self, other: Union[Float[Array, "N N"], LinearOperator] - ) -> Union[Float[Array, "N N"], LinearOperator]: - """Add covariance operator to another covariance operator. - - Args: - other (Union[Float[Array, "N N"], LinearOperator]): Covariance operator to add. - - Returns - ------- - Union[Float[Array, "N N"], LinearOperator]: Sum of the covariance operators. - """ - check_shapes_match(self.shape, other.shape) - return to_linear_operator(other) - - def _add_diagonal(self, other: DiagonalLinearOperator) -> DiagonalLinearOperator: - """Add diagonal to the covariance operator, useful for computing, Kxx + Io². - - Args: - other (DiagonalLinearOperator): Diagonal covariance operator to add to the covariance operator. - - Returns - ------- - DiagonalLinearOperator: Covariance operator with the diagonal added. - """ - check_shapes_match(self.shape, other.shape) - return other - - def __mul__(self, other: ScalarFloat) -> "ZeroLinearOperator": - """Multiply covariance operator by scalar. - - Args: - other (ConstantDiagonalLinearOperator): Scalar. - - Returns - ------- - ZeroLinearOperator: Covariance operator multiplied by a scalar. - """ - # TODO: check shapes. - return self - - def __matmul__( - self, other: Union[LinearOperator, Float[Array, "N M"]] - ) -> "ZeroLinearOperator": - """Matrix multiplication. - - Args: - other (Union[LinearOperator, Float[Array, "N M"]]): Matrix to multiply with. - - Returns - ------- - Float[Array, "N M"]: Result of matrix multiplication. - """ - check_shapes_match(self.shape, other.shape) - return self - - def to_dense(self) -> Float[Array, "N N"]: - """Construct dense Covariance matrix from the covariance operator. - - Returns - ------- - Float[Array, "N N"]: Dense covariance matrix. - """ - return jnp.zeros(self.shape) - - def to_root(self) -> "ZeroLinearOperator": - """ - Root of the covariance operator. - - Returns - ------- - ZeroLinearOperator: Root of the covariance operator. - """ - return self - - def log_det(self) -> ScalarFloat: - """Log determinant. - - Returns - ------- - ScalarFloat: Log determinant of the covariance matrix. - """ - return jnp.log(jnp.array(0.0)) - - def inverse(self) -> None: - """Inverse of the covariance operator. - - Raises - ------ - RuntimeError: ZeroLinearOperator is not invertible. - """ - raise RuntimeError("ZeroLinearOperator is not invertible.") - - def solve(self, rhs: Float[Array, "... M"]) -> None: - """Solve linear system. - - Raises - ------ - RuntimeError: ZeroLinearOperator is not invertible. - """ - raise RuntimeError("ZeroLinearOperator is not invertible.") - - @classmethod - def from_root(cls, root: "ZeroLinearOperator") -> "ZeroLinearOperator": - """Construct covariance operator from the root. - - Args: - root (ZeroLinearOperator): Root of the covariance operator. - - Returns - ------- - ZeroLinearOperator: Covariance operator. - """ - return root - - @classmethod - def from_dense(cls, dense: Float[Array, "N N"]) -> "ZeroLinearOperator": - """Construct covariance operator from the dense matrix. - - Args: - dense (Float[Array, "N N"]): Dense matrix. - - Returns - ------- - ZeroLinearOperator: Covariance operator. - """ - # TODO: check shapes. - n = dense.shape[0] - return ZeroLinearOperator(shape=(n, n)) - - -__all__ = [ - "ZeroLinearOperator", -] diff --git a/gpjax/lower_cholesky.py b/gpjax/lower_cholesky.py new file mode 100644 index 000000000..a47eaafd3 --- /dev/null +++ b/gpjax/lower_cholesky.py @@ -0,0 +1,43 @@ +# Copyright 2023 The GPJax Contributors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +import cola +import jax.numpy as jnp + +# TODO: Add lower_cholesky for other linear operators. + + +@cola.dispatch +def lower_cholesky(A: cola.ops.LinearOperator): # noqa: F811 + """Returns the lower Cholesky factor of a linear operator. + + Args: + A (cola.ops.LinearOperator): A linear operator. + + Returns: + cola.ops.LinearOperator: The lower Cholesky factor of A. + """ + + return cola.ops.Triangular(jnp.linalg.cholesky(A.to_dense()), lower=True) + + +@lower_cholesky.dispatch +def _(A: cola.ops.Diagonal): # noqa: F811 + return cola.ops.Diagonal(jnp.sqrt(A.diag)) + + +@lower_cholesky.dispatch +def _(A: cola.ops.Identity): # noqa: F811 + return A diff --git a/gpjax/objectives.py b/gpjax/objectives.py index 35b943731..2f6d7cd91 100644 --- a/gpjax/objectives.py +++ b/gpjax/objectives.py @@ -267,16 +267,20 @@ def variational_expectation( # Variational distribution q(f(·)) = N(f(·); μ(·), Σ(·, ·)) q = variational_family - # Compute variational mean, μ(x), and variance, √diag(Σ(x, x)), at the training + # TODO: This needs cleaning up! We are squeezing then broadcasting `mean` and `variance`, which is not ideal. + + # Compute variational mean, μ(x), and variance, diag(Σ(x, x)), at the training # inputs, x def q_moments(x): qx = q(x) - return qx.mean(), qx.variance() + return qx.mean().squeeze(), qx.covariance().squeeze() mean, variance = vmap(q_moments)(x[:, None]) # ≈ ∫[log(p(y|f(x))) q(f(x))] df(x) - expectation = q.posterior.likelihood.expected_log_likelihood(y, mean, variance) + expectation = q.posterior.likelihood.expected_log_likelihood( + y, mean[:, None], variance[:, None] + ) return expectation diff --git a/gpjax/variational_families.py b/gpjax/variational_families.py index 64cbb38d3..81da3049d 100644 --- a/gpjax/variational_families.py +++ b/gpjax/variational_families.py @@ -32,6 +32,7 @@ from gpjax.gaussian_distribution import GaussianDistribution from gpjax.gps import AbstractPosterior from gpjax.likelihoods import Gaussian +from gpjax.lower_cholesky import lower_cholesky from gpjax.typing import ( Array, ScalarFloat, @@ -187,7 +188,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: Kzz = kernel.gram(z) Kzz += cola.ops.I_like(Kzz) * self.jitter - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) muz = mean_function(z) # Unpack test inputs @@ -291,7 +292,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: Kzz = kernel.gram(z) Kzz += cola.ops.I_like(Kzz) * self.jitter - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) # Unpack test inputs t = test_inputs @@ -447,7 +448,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: Kzz = kernel.gram(z) Kzz += cola.ops.I_like(Kzz) * self.jitter - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) muz = mean_function(z) Ktt = kernel.gram(test_inputs) @@ -589,11 +590,11 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: S = cola.PSD(S) # S = sqrt sqrtᵀ - sqrt = cola.sqrt(S).to_dense() + sqrt = lower_cholesky(S) Kzz = kernel.gram(z) Kzz += cola.ops.I_like(Kzz) * self.jitter - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) muz = mean_function(z) # Unpack test inputs @@ -610,7 +611,7 @@ def predict(self, test_inputs: Float[Array, "N D"]) -> GaussianDistribution: Kzz_inv_Kzt = cola.solve(Lz.T, Lz_inv_Kzt) # Ktz Kzz⁻¹ sqrt - Ktz_Kzz_inv_sqrt = jnp.matmul(Kzz_inv_Kzt.T, sqrt) + Ktz_Kzz_inv_sqrt = Kzz_inv_Kzt.T @ sqrt # μt + Ktz Kzz⁻¹ (μ - μz) mean = mut + jnp.matmul(Kzz_inv_Kzt.T, mu - muz) @@ -676,7 +677,7 @@ def predict( Kzz += cola.ops.I_like(Kzz) * self.jitter # Lz Lzᵀ = Kzz - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) # Lz⁻¹ Kzx Lz_inv_Kzx = cola.solve(Lz, Kzx) diff --git a/pyproject.toml b/pyproject.toml index 9de64638d..c4b85a31d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ keywords = ["gaussian-processes jax machine-learning bayesian"] packages = [{ include = "gpjax" }] [tool.poetry.dependencies] -python = ">=3.8,<3.12" +python = ">=3.10,<3.12" optax = "^0.1.4" jaxtyping = "^0.2.15" tqdm = "^4.65.0" @@ -27,6 +27,7 @@ plum-dispatch = "^2.1.0" jax = ">=0.4.10" jaxlib = ">=0.4.10" orbax-checkpoint = ">=0.2.3" +cola-ml = "^0.0.1" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" @@ -168,7 +169,6 @@ convention = "numpy" "gpjax/scan.py" = ["PLR0913"] "gpjax/citation.py" = ["F811"] "tests/test_base/test_module.py" = ["PLR0915"] -"tests/test_linops/test_linear_operator.py" = ["PLR0913"] "tests/test_objectives.py" = ["PLR0913"] "docs/examples/barycentres.py" = ["PLR0913"] diff --git a/tests/conftest.py b/tests/conftest.py index 451074f1f..e12a1f72d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ -# from jaxtyping import install_import_hook +from jaxtyping import install_import_hook -# # import gpjax within import hook to apply beartype everywhere, before running tests -# with install_import_hook("gpjax", "beartype.beartype"): -# import gpjax # noqa: F401 +# import gpjax within import hook to apply beartype everywhere, before running tests +with install_import_hook("gpjax", "beartype.beartype"): + import gpjax # noqa: F401 diff --git a/tests/test_kernels/test_computation.py b/tests/test_kernels/test_computation.py index 1f27b0cc2..635e730fa 100644 --- a/tests/test_kernels/test_computation.py +++ b/tests/test_kernels/test_computation.py @@ -1,3 +1,8 @@ +import cola +from cola.ops import ( + Dense, + Diagonal, +) import jax.numpy as jnp import pytest @@ -38,14 +43,22 @@ def test_change_computation(kernel): x = jnp.linspace(-3.0, 3.0, 5).reshape(-1, 1) # The default computation is DenseKernelComputation - dense_matrix = kernel.gram(x).to_dense() + dense_linop = kernel.gram(x) + dense_matrix = dense_linop.to_dense() dense_diagonals = jnp.diag(dense_matrix) + assert isinstance(dense_linop, Dense) + assert cola.PSD in dense_linop.annotations + # Let's now change the computation to DiagonalKernelComputation kernel = kernel.replace(compute_engine=DiagonalKernelComputation()) - diagonal_matrix = kernel.gram(x).to_dense() + diagonal_linop = kernel.gram(x) + diagonal_matrix = diagonal_linop.to_dense() diag_entries = jnp.diag(diagonal_matrix) + assert isinstance(diagonal_linop, Diagonal) + assert cola.PSD in diagonal_linop.annotations + # The diagonal entries should be the same as the dense matrix assert jnp.allclose(diag_entries, dense_diagonals) @@ -54,9 +67,12 @@ def test_change_computation(kernel): # Let's now change the computation to ConstantDiagonalKernelComputation kernel = kernel.replace(compute_engine=ConstantDiagonalKernelComputation()) - constant_diagonal_matrix = kernel.gram(x).to_dense() + constant_diagonal_linop = kernel.gram(x) + constant_diagonal_matrix = constant_diagonal_linop.to_dense() constant_entries = jnp.diag(constant_diagonal_matrix) + assert cola.PSD in constant_diagonal_linop.annotations + # Assert all the diagonal entries are the same assert jnp.allclose(constant_entries, constant_entries[0]) diff --git a/tests/test_linops/__init__.py b/tests/test_linops/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/test_linops/test_constant_linear_operator.py b/tests/test_linops/test_constant_linear_operator.py deleted file mode 100644 index a9a325cfc..000000000 --- a/tests/test_linops/test_constant_linear_operator.py +++ /dev/null @@ -1,259 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import is_dataclass - -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import jax.tree_util as jtu -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.constant_diagonal_linear_operator import ( - ConstantDiagonalLinearOperator, -) -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator - - -def approx_equal(res: jnp.ndarray, actual: jnp.ndarray) -> bool: - """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_init(n: int) -> None: - value = jr.uniform(_PRNGKey, (1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - # Check types. - assert isinstance(constant_diag, ConstantDiagonalLinearOperator) - assert is_dataclass(constant_diag) - - # Check properties. - assert constant_diag.shape == (n, n) - assert constant_diag.dtype == jnp.float64 - assert constant_diag.ndim == 2 - assert constant_diag.size == n - - # Check pytree. - assert jtu.tree_leaves(constant_diag) == [value] # shape, dtype are static! - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_diag(n: int) -> None: - value = jr.uniform(_PRNGKey, (1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - res = constant_diag.diagonal() - actual = jnp.ones(n) * value - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - value = jr.uniform(_PRNGKey, (1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - actual = jnp.diag(jnp.ones(n) * value) - res = constant_diag.to_dense() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add_diagonal(n: int) -> None: - # Test adding two constant diagonal linear operators. - key_a, key_b = jr.split(_PRNGKey) - - value_a = jr.uniform(key_a, (1,)) - constant_diag_a = ConstantDiagonalLinearOperator(value=value_a, size=n) - - value_b = jr.uniform(key_b, (1,)) - constant_diag_b = ConstantDiagonalLinearOperator(value=value_b, size=n) - - res = constant_diag_a._add_diagonal(constant_diag_b) - actual = jnp.diag(jnp.ones(n) * (value_a + value_b)) - - assert isinstance(res, ConstantDiagonalLinearOperator) - assert res.shape == (n, n) - assert res.size == n - assert approx_equal(res.to_dense(), actual) - - # Test adding on the generic diagonal linear operator. - key = _PRNGKey - - value = jr.uniform(key, (1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - actual = jnp.diag(jnp.ones(n) * value) - - random_diag = DiagonalLinearOperator(jr.uniform(key, (n,))) - - res = constant_diag._add_diagonal(random_diag) - actual = jnp.diag(jnp.ones(n) * value + random_diag.diagonal()) - - assert isinstance(res, DiagonalLinearOperator) - assert res.shape == (n, n) - - assert approx_equal(res.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add(n: int) -> None: - key = _PRNGKey - - array = jr.uniform(_PRNGKey, shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - value = jr.uniform(key, (1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - # Add array. - res_left = constant_diag + array - res_right = array + constant_diag - - assert approx_equal(res_left.to_dense(), array + value * jnp.eye(n)) - assert approx_equal(res_right.to_dense(), array + value * jnp.eye(n)) - - # Add Dense. - array = jr.uniform(_PRNGKey, shape=(n, n)) - dense = DenseLinearOperator(matrix=array) - - res_left = constant_diag + dense - res_right = dense + constant_diag - actual = dense.to_dense() + value * jnp.eye(n) - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - # Add Diagonal. - diag = DiagonalLinearOperator(diag=entries) - - res_left = constant_diag + diag - res_right = diag + constant_diag - actual = diag.to_dense() + value * jnp.eye(n) - - assert isinstance(res_left, DiagonalLinearOperator) - assert isinstance(res_right, DiagonalLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_mul(n: int) -> None: - key, subkey = jr.split(_PRNGKey, 2) - constant = jr.uniform(key, shape=()) - value = jr.uniform(subkey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - res_left = constant_diag * constant - res_right = constant * constant_diag - - assert isinstance(res_left, ConstantDiagonalLinearOperator) - assert isinstance(res_right, ConstantDiagonalLinearOperator) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_matmul(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - res_left = constant_diag @ array - res_right = array @ constant_diag - - assert approx_equal(res_left, constant_diag.to_dense() @ array) - assert approx_equal(res_right, array @ constant_diag.to_dense()) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_solve(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - rhs = jr.uniform(_PRNGKey, shape=(n,)) - constant_diag.solve(rhs) - - assert approx_equal(constant_diag.solve(rhs), rhs / value) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_inverse(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - res = constant_diag.inverse() - - assert isinstance(res, ConstantDiagonalLinearOperator) - assert approx_equal(res.to_dense(), jnp.diag(1 / constant_diag.diagonal())) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_root(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - - res = constant_diag.to_root() - actual = ConstantDiagonalLinearOperator(value=jnp.sqrt(value), size=n) - - assert isinstance(res, ConstantDiagonalLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_log_det(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - res = constant_diag.log_det() - actual = jnp.log(value) * n - - approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_trace(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - constant_diag = ConstantDiagonalLinearOperator(value=value, size=n) - res = constant_diag.trace() - actual = value * n - - assert res == actual - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_root(n: int) -> None: - value = jr.uniform(_PRNGKey, shape=(1,)) - root = ConstantDiagonalLinearOperator(value=value, size=n) - constant_diag = ConstantDiagonalLinearOperator.from_root(root) - res = constant_diag.to_dense() - actual = jnp.diag(root.diagonal() ** 2) - - assert isinstance(constant_diag, ConstantDiagonalLinearOperator) - assert approx_equal(res, actual) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_dense(n: int) -> None: - dense = jr.uniform(_PRNGKey, shape=(n, n)) - res = ConstantDiagonalLinearOperator.from_dense(dense) - actual = jnp.diag(jnp.ones(n) * dense[0, 0]) - - assert isinstance(res, ConstantDiagonalLinearOperator) - assert approx_equal(res.to_dense(), actual) - assert res.shape == actual.shape diff --git a/tests/test_linops/test_dense_linear_operator.py b/tests/test_linops/test_dense_linear_operator.py deleted file mode 100644 index d28a68ef3..000000000 --- a/tests/test_linops/test_dense_linear_operator.py +++ /dev/null @@ -1,248 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import is_dataclass - -import jax -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import jax.tree_util as jtu -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.triangular_linear_operator import LowerTriangularLinearOperator - - -def approx_equal(res: jax.Array, actual: jax.Array) -> bool: - """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_init(n: int) -> None: - values = jr.uniform(_PRNGKey, (n, n)) - dense = DenseLinearOperator(values) - - # Check types. - assert isinstance(dense, DenseLinearOperator) - assert is_dataclass(dense) - - # Check properties. - assert dense.shape == (n, n) - assert dense.dtype == jnp.float64 - assert dense.ndim == 2 - - # Check pytree. - assert jtu.tree_leaves(dense) == [values] # shape, dtype are static! - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_diag(n: int) -> None: - values = jr.uniform(_PRNGKey, (n, n)) - dense = DenseLinearOperator(values) - res = dense.diagonal() - actual = values.diagonal() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - values = jr.uniform(_PRNGKey, (n, n)) - dense = DenseLinearOperator(values) - actual = values - res = dense.to_dense() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add_diagonal(n: int) -> None: - # Test adding generic diagonal linear operator. - key_a, key_b = jr.split(_PRNGKey) - - values_a = jr.uniform(key_a, (n, n)) - dense = DenseLinearOperator(values_a) - - values_b = jr.uniform(key_b, (n,)) - diag = DiagonalLinearOperator(values_b) - - res = dense._add_diagonal(diag) - actual = values_a + jnp.diag(values_b) - - assert isinstance(res, DenseLinearOperator) - assert res.shape == (n, n) - assert approx_equal(res.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add(n: int) -> None: - key = _PRNGKey - - array = jr.uniform(_PRNGKey, shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - values = jr.uniform(key, (n, n)) - dense = DenseLinearOperator(values) - - # Add array. - res_left = dense + array - res_right = array + dense - - assert approx_equal(res_left.to_dense(), array + values) - assert approx_equal(res_right.to_dense(), array + values) - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - - # Add Dense. - array = jr.uniform(_PRNGKey, shape=(n, n)) - dense = DenseLinearOperator(matrix=array) - - res_left = array + dense - res_right = dense + array - actual = dense.to_dense() + values - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - # Add Diagonal. - diag = DiagonalLinearOperator(diag=entries) - - res_left = dense + diag - res_right = diag + dense - actual = diag.to_dense() + values - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_mul(n: int) -> None: - key, subkey = jr.split(_PRNGKey, 2) - constant = jr.uniform(key, shape=()) - values = jr.uniform(subkey, shape=(n, n)) - dense = DenseLinearOperator(values) - - res_left = dense * constant - res_right = constant * dense - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), values * constant) - assert approx_equal(res_right.to_dense(), values * constant) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -@pytest.mark.parametrize("m", [1, 2, 5]) -def test_matmul(n: int, m: int) -> None: - array_left = jr.uniform(_PRNGKey, shape=(n, m)) - array_right = jr.uniform(_PRNGKey, shape=(m, n)) - - values = jr.uniform(_PRNGKey, shape=(n, n)) - values = values @ values.T - dense = DenseLinearOperator(values) - - res_left = dense @ array_left - res_right = array_right @ dense - - assert approx_equal(res_left, values @ array_left) - assert approx_equal(res_right, array_right @ values) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_solve(n: int) -> None: - sqrt = jr.uniform(_PRNGKey, shape=(n, n)) - values = sqrt @ sqrt.T - dense = DenseLinearOperator(values) - - assert approx_equal(dense.solve(values), jnp.eye(n)) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_inverse(n: int) -> None: - sqrt = jr.uniform(_PRNGKey, shape=(n, n)) - values = sqrt @ sqrt.T - dense = DenseLinearOperator(values) - res = dense.inverse() - - assert isinstance(res, DenseLinearOperator) - assert approx_equal(res.to_dense(), jnp.linalg.inv(values)) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_root(n: int) -> None: - sqrt = jr.uniform(_PRNGKey, shape=(n, n)) - values = sqrt @ sqrt.T - dense = DenseLinearOperator(values) - res = dense.to_root() - actual = jnp.linalg.cholesky(values) - - assert isinstance(res, LowerTriangularLinearOperator) - assert approx_equal(res.to_dense(), actual) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_log_det(n: int) -> None: - sqrt = jr.uniform(_PRNGKey, shape=(n, n)) - values = sqrt @ sqrt.T - dense = DenseLinearOperator(values) - res = dense.log_det() - actual = jnp.linalg.slogdet(values)[1] - - approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_trace(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n, n)) - dense = DenseLinearOperator(values) - res = dense.trace() - actual = jnp.diag(values).sum() - - assert res == actual - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_root(n: int) -> None: - sqrt = jr.uniform(_PRNGKey, shape=(n, n)) - values = sqrt @ sqrt.T - L = jnp.linalg.cholesky(values) - root = LowerTriangularLinearOperator.from_dense(L) - dense = DenseLinearOperator.from_root(root) - - assert isinstance(dense, DenseLinearOperator) - assert approx_equal(dense.to_root().to_dense(), root.to_dense()) - assert approx_equal(dense.to_dense(), values) - assert root.shape == dense.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_dense(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n, n)) - res = DenseLinearOperator.from_dense(values) - actual = DenseLinearOperator(values) - - assert isinstance(res, DenseLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape diff --git a/tests/test_linops/test_diagonal_linear_operator.py b/tests/test_linops/test_diagonal_linear_operator.py deleted file mode 100644 index 991622f3a..000000000 --- a/tests/test_linops/test_diagonal_linear_operator.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import is_dataclass - -import jax -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import jax.tree_util as jtu -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator - - -def approx_equal(res: jax.Array, actual: jax.Array) -> bool: - """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_init(n: int) -> None: - values = jr.uniform(_PRNGKey, (n,)) - diag = DiagonalLinearOperator(values) - - # Check types. - assert isinstance(diag, DiagonalLinearOperator) - assert is_dataclass(diag) - - # Check properties. - assert diag.shape == (n, n) - assert diag.dtype == jnp.float64 - assert diag.ndim == 2 - - # Check pytree. - assert jtu.tree_leaves(diag) == [values] # shape, dtype are static! - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_diag(n: int) -> None: - entries = jr.uniform(_PRNGKey, (n,)) - diag = DiagonalLinearOperator(entries) - res = diag.diagonal() - actual = entries - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - values = jr.uniform(_PRNGKey, (n,)) - diag = DiagonalLinearOperator(values) - actual = jnp.diag(values) - res = diag.to_dense() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add_diagonal(n: int) -> None: - # Test adding two diagonal linear operators. - key_a, key_b = jr.split(_PRNGKey) - - values_a = jr.uniform(key_a, (n,)) - diag_a = DiagonalLinearOperator(values_a) - - values_b = jr.uniform(key_b, (n,)) - diag_b = DiagonalLinearOperator(values_b) - - res = diag_a._add_diagonal(diag_b) - actual = jnp.diag(values_a + values_b) - - assert isinstance(res, DiagonalLinearOperator) - assert res.shape == (n, n) - assert approx_equal(res.to_dense(), actual) - - # Test adding on the generic diagonal linear operator. - key = _PRNGKey - - values = jr.uniform(key, (n,)) - diag = DiagonalLinearOperator(values) - actual = jnp.diag(values) - - random_diag = DiagonalLinearOperator(jr.uniform(key, (n,))) - - res = diag._add_diagonal(random_diag) - actual = jnp.diag(values + random_diag.diagonal()) - - assert isinstance(res, DiagonalLinearOperator) - assert res.shape == (n, n) - - assert approx_equal(res.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add(n: int) -> None: - key = _PRNGKey - - array = jr.uniform(_PRNGKey, shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - values = jr.uniform(key, (n,)) - diag = DiagonalLinearOperator(values) - - # Add array. - res_left = diag + array - res_right = array + diag - - assert approx_equal(res_left.to_dense(), array + jnp.diag(values)) - assert approx_equal(res_right.to_dense(), array + jnp.diag(values)) - - # Add Dense. - array = jr.uniform(_PRNGKey, shape=(n, n)) - dense = DenseLinearOperator(matrix=array) - - res_left = diag + dense - res_right = dense + diag - actual = dense.to_dense() + jnp.diag(values) - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - # Add Diagonal. - diag = DiagonalLinearOperator(diag=entries) - - res_left = diag + diag - res_right = diag + diag - actual = diag.to_dense() + jnp.diag(values) - - assert isinstance(res_left, DiagonalLinearOperator) - assert isinstance(res_right, DiagonalLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_mul(n: int) -> None: - key, subkey = jr.split(_PRNGKey, 2) - constant = jr.uniform(key, shape=()) - values = jr.uniform(subkey, shape=(n,)) - diag = DiagonalLinearOperator(values) - - res_left = diag * constant - res_right = constant * diag - - assert isinstance(res_left, DiagonalLinearOperator) - assert isinstance(res_right, DiagonalLinearOperator) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_matmul(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - - res_left = diag @ array - res_right = array @ diag - - assert approx_equal(res_left, diag.to_dense() @ array) - assert approx_equal(res_right, array @ diag.to_dense()) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_solve(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - rhs = jr.uniform(_PRNGKey, shape=(n,)) - diag.solve(rhs) - - assert approx_equal(diag.solve(rhs), rhs / values) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_inverse(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - res = diag.inverse() - - assert isinstance(res, DiagonalLinearOperator) - assert approx_equal(res.to_dense(), jnp.diag(1 / diag.diagonal())) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_root(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - res = diag.to_root() - actual = DiagonalLinearOperator(jnp.sqrt(values)) - - assert isinstance(res, DiagonalLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_log_det(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - res = diag.log_det() - actual = jnp.linalg.slogdet(jnp.diag(values))[1] - - approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_trace(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(values) - res = diag.trace() - actual = values.sum() - - assert res == actual - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_root(n: int) -> None: - values = jr.uniform(_PRNGKey, shape=(n,)) - root = DiagonalLinearOperator(values) - diag = DiagonalLinearOperator.from_root(root) - res = diag.to_dense() - actual = jnp.diag(root.diagonal() ** 2) - - assert isinstance(diag, DiagonalLinearOperator) - assert approx_equal(res, actual) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_dense(n: int) -> None: - dense = jr.uniform(_PRNGKey, shape=(n, n)) - res = DiagonalLinearOperator.from_dense(dense) - actual = jnp.diag(dense.diagonal()) - - assert isinstance(res, DiagonalLinearOperator) - assert approx_equal(res.to_dense(), actual) - assert res.shape == actual.shape diff --git a/tests/test_linops/test_identity_linear_operator.py b/tests/test_linops/test_identity_linear_operator.py deleted file mode 100644 index b8a79f507..000000000 --- a/tests/test_linops/test_identity_linear_operator.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import is_dataclass - -import jax -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import jax.tree_util as jtu -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.constant_diagonal_linear_operator import ( - ConstantDiagonalLinearOperator, -) -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.identity_linear_operator import IdentityLinearOperator - - -def approx_equal(res: jax.Array, actual: jax.Array) -> bool: - """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_init(n: int) -> None: - id = IdentityLinearOperator(size=n) - - # Check types. - assert isinstance(id, ConstantDiagonalLinearOperator) - assert is_dataclass(id) - - # Check properties. - assert id.shape == (n, n) - assert id.dtype == jnp.float64 - assert id.ndim == 2 - assert id.size == n - - # Check pytree. - assert jtu.tree_leaves(id) == [1.0] # shape, dtype are static! - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_diag(n: int) -> None: - id = IdentityLinearOperator(size=n) - res = id.diagonal() - actual = jnp.ones(n) - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - id = IdentityLinearOperator(size=n) - actual = jnp.eye(n) - res = id.to_dense() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add_diagonal(n: int) -> None: - id = IdentityLinearOperator(size=n) - entries = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(diag=entries) - id_add_diag = id._add_diagonal(diag) - - assert isinstance(id_add_diag, DiagonalLinearOperator) - - res = id_add_diag.to_dense() - actual = jnp.eye(n) * (1.0 + entries) - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - id = IdentityLinearOperator(size=n) - - # Add array. - res_left = id + array - res_right = array + id - - actual = array + jnp.eye(n) - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual) - assert approx_equal(res_right.to_dense(), actual) - - # Add Dense. - dense_lo = DenseLinearOperator(matrix=array) - - res_left = id + dense_lo - res_right = dense_lo + id - actual = DenseLinearOperator(matrix=array + jnp.eye(n)) - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual.to_dense()) - assert approx_equal(res_right.to_dense(), actual.to_dense()) - - # Add Diagonal. - diag = DiagonalLinearOperator(diag=entries) - - res_left = id + diag - res_right = diag + id - actual = DiagonalLinearOperator(diag=entries + jnp.ones(n)) - - assert isinstance(res_left, DiagonalLinearOperator) - assert isinstance(res_right, DiagonalLinearOperator) - assert approx_equal(res_left.to_dense(), actual.to_dense()) - assert approx_equal(res_right.to_dense(), actual.to_dense()) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_mul(n: int) -> None: - constant = jr.uniform(_PRNGKey, shape=()) - id = IdentityLinearOperator(size=n) - - res_left = id * constant - res_right = constant * id - - assert isinstance(res_left, ConstantDiagonalLinearOperator) - assert isinstance(res_right, ConstantDiagonalLinearOperator) - assert approx_equal(res_left.to_dense(), constant * jnp.eye(n)) - assert approx_equal(res_right.to_dense(), constant * jnp.eye(n)) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_matmul(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - id = IdentityLinearOperator(size=n) - res_left = id @ array - res_right = array @ id - assert isinstance(res_left, jax.Array) - assert isinstance(res_right, jax.Array) - assert approx_equal(res_left, array) - assert approx_equal(res_right, array) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -@pytest.mark.parametrize("m", [1, 2, 5]) -def test_solve(n: int, m: int) -> None: - id = IdentityLinearOperator(size=n) - rhs = jr.uniform(_PRNGKey, shape=(n, m)) - res = id.solve(rhs) - - assert isinstance(res, jax.Array) - assert approx_equal(res, rhs) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_root(n: int) -> None: - id = IdentityLinearOperator(size=n) - res = id.to_root() - assert isinstance(res, IdentityLinearOperator) - assert approx_equal(res.to_dense(), jnp.eye(n)) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_root(n: int) -> None: - id = IdentityLinearOperator(size=n) - res = IdentityLinearOperator.from_root(id) - assert isinstance(res, IdentityLinearOperator) - assert approx_equal(res.to_dense(), jnp.eye(n)) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_dense(n: int) -> None: - dense = jr.uniform(_PRNGKey, shape=(n, n)) - res = IdentityLinearOperator.from_dense(dense) - assert isinstance(res, IdentityLinearOperator) - assert approx_equal(res.to_dense(), jnp.eye(n)) - - -__all__ = [ - "IdentityLinearOperator", -] diff --git a/tests/test_linops/test_linear_operator.py b/tests/test_linops/test_linear_operator.py deleted file mode 100644 index 9af70212a..000000000 --- a/tests/test_linops/test_linear_operator.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - -from dataclasses import ( - dataclass, - is_dataclass, -) - -import jax.numpy as jnp -import jax.tree_util as jtu -import pytest - -from gpjax.base import static_field -from gpjax.linops.linear_operator import LinearOperator - - -def test_abstract_operator() -> None: - # Test abstract linear operator raises an error. - with pytest.raises(TypeError): - LinearOperator() - - # Test dataclass wrapped abstract linear operator raise an error. - with pytest.raises(TypeError): - dataclass(LinearOperator)() - - -@pytest.mark.parametrize("test_dataclass", [True, False]) -@pytest.mark.parametrize("shape", [(1, 1), (2, 3), (4, 5, 6), [7, 8]]) -@pytest.mark.parametrize("dtype", [jnp.float32, jnp.float64]) -def test_instantiate_no_attributes(test_dataclass, shape, dtype) -> None: - # Test can instantiate a linear operator with the abstract methods defined. - class DummyLinearOperator(LinearOperator): - def diagonal(self, *args, **kwargs): - pass - - def shape(self, *args, **kwargs): - pass - - def dtype(self, *args, **kwargs): - pass - - def __mul__(self, *args, **kwargs): - """Multiply linear operator by scalar.""" - - def _add_diagonal(self, *args, **kwargs): - pass - - def __matmul__(self, *args, **kwargs): - """Matrix multiplication.""" - - def to_dense(self, *args, **kwargs): - pass - - @classmethod - def from_dense(cls, *args, **kwargs): - pass - - # Ensure we check dataclass case. - if test_dataclass: - DummyLinearOperator = dataclass(DummyLinearOperator) - - # Initialise linear operator. - linop = DummyLinearOperator(shape=shape, dtype=dtype) - - # Check types. - assert isinstance(linop, DummyLinearOperator) - assert isinstance(linop, LinearOperator) - - if test_dataclass: - assert is_dataclass(linop) - - # Check properties. - assert linop.shape == shape - assert linop.dtype == dtype - assert linop.ndim == len(shape) - - # Check pytree. - assert jtu.tree_leaves(linop) == [] # shape and dtype are static! - - -@pytest.mark.parametrize("test_dataclass", [True, False]) -@pytest.mark.parametrize("shape", [(1, 1), (2, 3), (4, 5, 6), [7, 8]]) -@pytest.mark.parametrize("dtype", [jnp.float32, jnp.float64]) -def test_instantiate_with_attributes(test_dataclass, shape, dtype) -> None: - """Test if the covariance operator can be instantiated with attribute annotations.""" - - class DummyLinearOperator(LinearOperator): - a: int - b: int = static_field() # Lets have a static attribute here. - c: int - - def __init__(self, shape, dtype, a=1, b=2, c=3): - self.a = a - self.b = b - self.c = c - self.shape = shape - self.dtype = dtype - - def diagonal(self, *args, **kwargs): - pass - - def shape(self, *args, **kwargs): - pass - - def dtype(self, *args, **kwargs): - pass - - def __mul__(self, *args, **kwargs): - """Multiply linear operator by scalar.""" - - def _add_diagonal(self, *args, **kwargs): - pass - - def __matmul__(self, *args, **kwargs): - """Matrix multiplication.""" - - def to_dense(self, *args, **kwargs): - pass - - @classmethod - def from_dense(cls, *args, **kwargs): - pass - - # Ensure we check dataclass case. - if test_dataclass: - DummyLinearOperator = dataclass(DummyLinearOperator) - - # Initialise linear operator. - linop = DummyLinearOperator(shape=shape, dtype=dtype) - - # Check types. - assert isinstance(linop, DummyLinearOperator) - assert isinstance(linop, LinearOperator) - - if test_dataclass: - assert is_dataclass(linop) - - # Check properties. - assert linop.shape == shape - assert linop.dtype == dtype - assert linop.ndim == len(shape) - - # Check pytree. - assert jtu.tree_leaves(linop) == [1, 3] # b, shape, dtype are static! diff --git a/tests/test_linops/test_triangular_linear_operator.py b/tests/test_linops/test_triangular_linear_operator.py deleted file mode 100644 index 02b64e579..000000000 --- a/tests/test_linops/test_triangular_linear_operator.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - -from jax.config import config -import jax.random as jr -from jax.random import KeyArray - -# Test settings: -key: KeyArray = jr.PRNGKey(seed=42) -jitter: float = 1e-6 -atol: float = 1e-6 -config.update("jax_enable_x64", True) diff --git a/tests/test_linops/test_utils.py b/tests/test_linops/test_utils.py deleted file mode 100644 index 3f7581308..000000000 --- a/tests/test_linops/test_utils.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.identity_linear_operator import IdentityLinearOperator -from gpjax.linops.utils import ( - identity, - to_dense, -) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_identity(n: int) -> None: - id = identity(n) - assert isinstance(id, IdentityLinearOperator) - assert id.shape == (n, n) - assert id.size == n - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - mat = jr.uniform(_PRNGKey, (n, n)) - lo = DenseLinearOperator(mat) - - assert jnp.allclose(to_dense(lo), lo.to_dense()) - assert jnp.allclose(to_dense(mat), mat) diff --git a/tests/test_linops/test_zero_linear_operator.py b/tests/test_linops/test_zero_linear_operator.py deleted file mode 100644 index 674c2033a..000000000 --- a/tests/test_linops/test_zero_linear_operator.py +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright 2022 The JaxLinOp Contributors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== - - -from dataclasses import is_dataclass - -import jax -from jax.config import config -import jax.numpy as jnp -import jax.random as jr -import jax.tree_util as jtu -import pytest - -# Enable Float64 for more stable matrix inversions. -config.update("jax_enable_x64", True) -_PRNGKey = jr.PRNGKey(42) - -from gpjax.linops.dense_linear_operator import DenseLinearOperator -from gpjax.linops.diagonal_linear_operator import DiagonalLinearOperator -from gpjax.linops.zero_linear_operator import ZeroLinearOperator - - -def approx_equal(res: jax.Array, actual: jax.Array) -> bool: - """Check if two arrays are approximately equal.""" - return jnp.linalg.norm(res - actual) < 1e-6 - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_init(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - # Check types. - assert isinstance(zero, ZeroLinearOperator) - assert is_dataclass(zero) - - # Check properties. - assert zero.shape == (n, n) - assert zero.dtype == jnp.float64 - assert zero.ndim == 2 - - # Check pytree. - assert jtu.tree_leaves(zero) == [] # shape, dtype are static! - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_diag(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - res = zero.diagonal() - actual = jnp.zeros(n) - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_dense(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - actual = jnp.zeros(shape=(n, n)) - res = zero.to_dense() - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add_diagonal(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - diag = DiagonalLinearOperator(diag=entries) - zero_add_diag = zero._add_diagonal(diag) - - assert isinstance(zero_add_diag, DiagonalLinearOperator) - - res = zero_add_diag.to_dense() - actual = jnp.eye(n) * entries - assert approx_equal(res, actual) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_add(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - entries = jr.uniform(_PRNGKey, shape=(n,)) - zero = ZeroLinearOperator(shape=(n, n)) - - # Add array. - res_left = zero + array - res_right = array + zero - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - - # Add Dense. - dense_lo = DenseLinearOperator(matrix=array) - - res_left = zero + dense_lo - res_right = dense_lo + zero - actual = dense_lo - - assert isinstance(res_left, DenseLinearOperator) - assert isinstance(res_right, DenseLinearOperator) - assert approx_equal(res_left.to_dense(), actual.to_dense()) - assert approx_equal(res_right.to_dense(), actual.to_dense()) - - # Add Diagonal. - diag = DiagonalLinearOperator(diag=entries) - - res_left = zero + diag - res_right = diag + zero - actual = diag - - assert isinstance(res_left, DiagonalLinearOperator) - assert isinstance(res_right, DiagonalLinearOperator) - assert approx_equal(res_left.to_dense(), actual.to_dense()) - assert approx_equal(res_right.to_dense(), actual.to_dense()) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_mul(n: int) -> None: - constant = jr.uniform(_PRNGKey, shape=()) - zero = ZeroLinearOperator(shape=(n, n)) - - res_left = zero * constant - res_right = constant * zero - - assert isinstance(res_left, ZeroLinearOperator) - assert isinstance(res_right, ZeroLinearOperator) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_matmul(n: int) -> None: - array = jr.uniform(_PRNGKey, shape=(n, n)) - zero = ZeroLinearOperator(shape=(n, n)) - - res_left = zero @ array - res_right = array @ zero - - assert isinstance(res_left, ZeroLinearOperator) - assert isinstance(res_right, ZeroLinearOperator) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_solve(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - with pytest.raises(RuntimeError): - rhs = jr.uniform(_PRNGKey, shape=(n,)) - zero.solve(rhs) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_inverse(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - with pytest.raises(RuntimeError): - zero.inverse() - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_to_root(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - res = zero.to_root() - actual = zero - - assert isinstance(res, ZeroLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_log_det(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - assert zero.log_det() == jnp.log(0.0) - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_trace(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - res = zero.trace() - actual = 0.0 - - assert res == actual - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_root(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - res = ZeroLinearOperator.from_root(zero) - actual = zero - - assert isinstance(res, ZeroLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape - - -@pytest.mark.parametrize("n", [1, 2, 5]) -def test_from_dense(n: int) -> None: - zero = ZeroLinearOperator(shape=(n, n)) - - dense = jr.uniform(_PRNGKey, shape=(n, n)) - res = ZeroLinearOperator.from_dense(dense) - actual = zero - - assert isinstance(res, ZeroLinearOperator) - assert approx_equal(res.to_dense(), actual.to_dense()) - assert res.shape == actual.shape diff --git a/tests/test_lower_cholesky.py b/tests/test_lower_cholesky.py new file mode 100644 index 000000000..e00c1ea23 --- /dev/null +++ b/tests/test_lower_cholesky.py @@ -0,0 +1,35 @@ +from cola.ops import ( + Dense, + Diagonal, + I_like, + Identity, + Triangular, +) +import jax.numpy as jnp + +from gpjax.lower_cholesky import lower_cholesky + + +def test_dense() -> None: + array = jnp.array([[3.0, 1.0], [1.0, 3.0]]) + A = Dense(array) + + L = lower_cholesky(A) + assert isinstance(L, Triangular) + assert jnp.allclose(L.to_dense(), jnp.linalg.cholesky(array)) + + +def test_diagonal() -> None: + array = jnp.array([1.0, 2.0]) + A = Diagonal(array) + + L = lower_cholesky(A) + assert isinstance(L, Diagonal) + assert jnp.allclose(L.to_dense(), jnp.diag(jnp.sqrt(array))) + + +def test_identity() -> None: + A = I_like(jnp.eye(2)) + L = lower_cholesky(A) + assert isinstance(L, Identity) + assert jnp.allclose(L.to_dense(), jnp.eye(2)) From 4ba6c038e6bca9e6d564d18d8bad8119a030f9b3 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Sat, 26 Aug 2023 19:26:47 +0100 Subject: [PATCH 58/76] Resolve plum. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c4b85a31d..80f057f84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,11 +23,11 @@ tqdm = "^4.65.0" simple-pytree = "^0.1.7" tensorflow-probability = "^0.19.0" beartype = "^0.13.1" -plum-dispatch = "^2.1.0" jax = ">=0.4.10" jaxlib = ">=0.4.10" orbax-checkpoint = ">=0.2.3" cola-ml = "^0.0.1" +cola-plum-dispatch = "^0.1.1" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" From 8c4d1e64d9ffecc0f06a11e594983ea3de3adb2a Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Sat, 26 Aug 2023 19:54:38 +0100 Subject: [PATCH 59/76] Resolve rebase from branch. Resolve rebase from branch. --- gpjax/gaussian_distribution.py | 12 +- poetry.lock | 5953 ++++++++++++++------------- tests/test_gaussian_distribution.py | 2 +- 3 files changed, 3167 insertions(+), 2800 deletions(-) diff --git a/gpjax/gaussian_distribution.py b/gpjax/gaussian_distribution.py index 131f8955f..f077f6031 100644 --- a/gpjax/gaussian_distribution.py +++ b/gpjax/gaussian_distribution.py @@ -20,7 +20,10 @@ Tuple, ) import cola -from cola.ops import Identity +from cola.ops import ( + Dense, + Identity, +) from jax import vmap import jax.numpy as jnp import jax.random as jr @@ -168,12 +171,13 @@ def log_prob( mu = self.loc sigma = self.scale n = mu.shape[-1] + if mask is not None: y = jnp.where(mask, 0.0, y) mu = jnp.where(mask, 0.0, mu) - sigma_masked = jnp.where(mask[None] + mask[:, None], 0.0, sigma.matrix) - sigma = sigma.replace( - matrix=jnp.where(jnp.diag(mask), 1 / (2 * jnp.pi), sigma_masked) + sigma_masked = jnp.where(mask[None] + mask[:, None], 0.0, sigma.to_dense()) + sigma = cola.PSD( + Dense(jnp.where(jnp.diag(mask), 1 / (2 * jnp.pi), sigma_masked)) ) # diff, y - µ diff --git a/poetry.lock b/poetry.lock index ee51aeb5c..c8c8daf90 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. + [[package]] name = "absl-py" version = "1.4.0" @@ -5,6 +7,10 @@ description = "Abseil Python Common Libraries, see https://github.com/abseil/abs category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, + {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, +] [[package]] name = "absolufy-imports" @@ -13,6 +19,10 @@ description = "A tool to automatically replace relative imports with absolute on category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "absolufy_imports-0.3.1-py2.py3-none-any.whl", hash = "sha256:49bf7c753a9282006d553ba99217f48f947e3eef09e18a700f8a82f75dc7fc5c"}, + {file = "absolufy_imports-0.3.1.tar.gz", hash = "sha256:c90638a6c0b66826d1fb4880ddc20ef7701af34192c94faf40b95d32b59f9793"}, +] [[package]] name = "affine" @@ -21,6 +31,10 @@ description = "Matrices describing affine transformation of the plane" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, + {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, +] [package.extras] dev = ["coveralls", "flake8", "pydocstyle"] @@ -28,11 +42,100 @@ test = ["pytest (>=4.6)", "pytest-cov"] [[package]] name = "aiohttp" -version = "3.8.4" +version = "3.8.5" description = "Async http client/server framework (asyncio)" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a94159871304770da4dd371f4291b20cac04e8c94f11bdea1c3478e557fbe0d8"}, + {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:13bf85afc99ce6f9ee3567b04501f18f9f8dbbb2ea11ed1a2e079670403a7c84"}, + {file = "aiohttp-3.8.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ce2ac5708501afc4847221a521f7e4b245abf5178cf5ddae9d5b3856ddb2f3a"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96943e5dcc37a6529d18766597c491798b7eb7a61d48878611298afc1fca946c"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ad5c3c4590bb3cc28b4382f031f3783f25ec223557124c68754a2231d989e2b"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c413c633d0512df4dc7fd2373ec06cc6a815b7b6d6c2f208ada7e9e93a5061d"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df72ac063b97837a80d80dec8d54c241af059cc9bb42c4de68bd5b61ceb37caa"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c48c5c0271149cfe467c0ff8eb941279fd6e3f65c9a388c984e0e6cf57538e14"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:368a42363c4d70ab52c2c6420a57f190ed3dfaca6a1b19afda8165ee16416a82"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7607ec3ce4993464368505888af5beb446845a014bc676d349efec0e05085905"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0d21c684808288a98914e5aaf2a7c6a3179d4df11d249799c32d1808e79503b5"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:312fcfbacc7880a8da0ae8b6abc6cc7d752e9caa0051a53d217a650b25e9a691"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad093e823df03bb3fd37e7dec9d4670c34f9e24aeace76808fc20a507cace825"}, + {file = "aiohttp-3.8.5-cp310-cp310-win32.whl", hash = "sha256:33279701c04351a2914e1100b62b2a7fdb9a25995c4a104259f9a5ead7ed4802"}, + {file = "aiohttp-3.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:6e4a280e4b975a2e7745573e3fc9c9ba0d1194a3738ce1cbaa80626cc9b4f4df"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae871a964e1987a943d83d6709d20ec6103ca1eaf52f7e0d36ee1b5bebb8b9b9"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:461908b2578955045efde733719d62f2b649c404189a09a632d245b445c9c975"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72a860c215e26192379f57cae5ab12b168b75db8271f111019509a1196dfc780"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc14be025665dba6202b6a71cfcdb53210cc498e50068bc088076624471f8bb9"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8af740fc2711ad85f1a5c034a435782fbd5b5f8314c9a3ef071424a8158d7f6b"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:841cd8233cbd2111a0ef0a522ce016357c5e3aff8a8ce92bcfa14cef890d698f"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed1c46fb119f1b59304b5ec89f834f07124cd23ae5b74288e364477641060ff"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84f8ae3e09a34f35c18fa57f015cc394bd1389bce02503fb30c394d04ee6b938"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62360cb771707cb70a6fd114b9871d20d7dd2163a0feafe43fd115cfe4fe845e"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23fb25a9f0a1ca1f24c0a371523546366bb642397c94ab45ad3aedf2941cec6a"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0ba0d15164eae3d878260d4c4df859bbdc6466e9e6689c344a13334f988bb53"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5d20003b635fc6ae3f96d7260281dfaf1894fc3aa24d1888a9b2628e97c241e5"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0175d745d9e85c40dcc51c8f88c74bfbaef9e7afeeeb9d03c37977270303064c"}, + {file = "aiohttp-3.8.5-cp311-cp311-win32.whl", hash = "sha256:2e1b1e51b0774408f091d268648e3d57f7260c1682e7d3a63cb00d22d71bb945"}, + {file = "aiohttp-3.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:043d2299f6dfdc92f0ac5e995dfc56668e1587cea7f9aa9d8a78a1b6554e5755"}, + {file = "aiohttp-3.8.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cae533195e8122584ec87531d6df000ad07737eaa3c81209e85c928854d2195c"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f21e83f355643c345177a5d1d8079f9f28b5133bcd154193b799d380331d5d3"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a75ef35f2df54ad55dbf4b73fe1da96f370e51b10c91f08b19603c64004acc"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e2e9839e14dd5308ee773c97115f1e0a1cb1d75cbeeee9f33824fa5144c7634"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44e65da1de4403d0576473e2344828ef9c4c6244d65cf4b75549bb46d40b8dd"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d847e4cde6ecc19125ccbc9bfac4a7ab37c234dd88fbb3c5c524e8e14da543"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c7a815258e5895d8900aec4454f38dca9aed71085f227537208057853f9d13f2"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:8b929b9bd7cd7c3939f8bcfffa92fae7480bd1aa425279d51a89327d600c704d"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5db3a5b833764280ed7618393832e0853e40f3d3e9aa128ac0ba0f8278d08649"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:a0215ce6041d501f3155dc219712bc41252d0ab76474615b9700d63d4d9292af"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fd1ed388ea7fbed22c4968dd64bab0198de60750a25fe8c0c9d4bef5abe13824"}, + {file = "aiohttp-3.8.5-cp36-cp36m-win32.whl", hash = "sha256:6e6783bcc45f397fdebc118d772103d751b54cddf5b60fbcc958382d7dd64f3e"}, + {file = "aiohttp-3.8.5-cp36-cp36m-win_amd64.whl", hash = "sha256:b5411d82cddd212644cf9360879eb5080f0d5f7d809d03262c50dad02f01421a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:01d4c0c874aa4ddfb8098e85d10b5e875a70adc63db91f1ae65a4b04d3344cda"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5980a746d547a6ba173fd5ee85ce9077e72d118758db05d229044b469d9029a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a482e6da906d5e6e653be079b29bc173a48e381600161c9932d89dfae5942ef"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80bd372b8d0715c66c974cf57fe363621a02f359f1ec81cba97366948c7fc873"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1161b345c0a444ebcf46bf0a740ba5dcf50612fd3d0528883fdc0eff578006a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd56db019015b6acfaaf92e1ac40eb8434847d9bf88b4be4efe5bfd260aee692"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:153c2549f6c004d2754cc60603d4668899c9895b8a89397444a9c4efa282aaf4"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4a01951fabc4ce26ab791da5f3f24dca6d9a6f24121746eb19756416ff2d881b"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bfb9162dcf01f615462b995a516ba03e769de0789de1cadc0f916265c257e5d8"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7dde0009408969a43b04c16cbbe252c4f5ef4574ac226bc8815cd7342d2028b6"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4149d34c32f9638f38f544b3977a4c24052042affa895352d3636fa8bffd030a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-win32.whl", hash = "sha256:68c5a82c8779bdfc6367c967a4a1b2aa52cd3595388bf5961a62158ee8a59e22"}, + {file = "aiohttp-3.8.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2cf57fb50be5f52bda004b8893e63b48530ed9f0d6c96c84620dc92fe3cd9b9d"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eca4bf3734c541dc4f374ad6010a68ff6c6748f00451707f39857f429ca36ced"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1274477e4c71ce8cfe6c1ec2f806d57c015ebf84d83373676036e256bc55d690"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c543e54710d6158fc6f439296c7865b29e0b616629767e685a7185fab4a6b9"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:910bec0c49637d213f5d9877105d26e0c4a4de2f8b1b29405ff37e9fc0ad52b8"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5443910d662db951b2e58eb70b0fbe6b6e2ae613477129a5805d0b66c54b6cb7"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e460be6978fc24e3df83193dc0cc4de46c9909ed92dd47d349a452ef49325b7"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb1558def481d84f03b45888473fc5a1f35747b5f334ef4e7a571bc0dfcb11f8"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34dd0c107799dcbbf7d48b53be761a013c0adf5571bf50c4ecad5643fe9cfcd0"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aa1990247f02a54185dc0dff92a6904521172a22664c863a03ff64c42f9b5410"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0e584a10f204a617d71d359fe383406305a4b595b333721fa50b867b4a0a1548"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a3cf433f127efa43fee6b90ea4c6edf6c4a17109d1d037d1a52abec84d8f2e42"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c11f5b099adafb18e65c2c997d57108b5bbeaa9eeee64a84302c0978b1ec948b"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:84de26ddf621d7ac4c975dbea4c945860e08cccde492269db4e1538a6a6f3c35"}, + {file = "aiohttp-3.8.5-cp38-cp38-win32.whl", hash = "sha256:ab88bafedc57dd0aab55fa728ea10c1911f7e4d8b43e1d838a1739f33712921c"}, + {file = "aiohttp-3.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:5798a9aad1879f626589f3df0f8b79b3608a92e9beab10e5fda02c8a2c60db2e"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a6ce61195c6a19c785df04e71a4537e29eaa2c50fe745b732aa937c0c77169f3"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:773dd01706d4db536335fcfae6ea2440a70ceb03dd3e7378f3e815b03c97ab51"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f83a552443a526ea38d064588613aca983d0ee0038801bc93c0c916428310c28"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7372f7341fcc16f57b2caded43e81ddd18df53320b6f9f042acad41f8e049a"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea353162f249c8097ea63c2169dd1aa55de1e8fecbe63412a9bc50816e87b761"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d47ae48db0b2dcf70bc8a3bc72b3de86e2a590fc299fdbbb15af320d2659de"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d827176898a2b0b09694fbd1088c7a31836d1a505c243811c87ae53a3f6273c1"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3562b06567c06439d8b447037bb655ef69786c590b1de86c7ab81efe1c9c15d8"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4e874cbf8caf8959d2adf572a78bba17cb0e9d7e51bb83d86a3697b686a0ab4d"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6809a00deaf3810e38c628e9a33271892f815b853605a936e2e9e5129762356c"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:33776e945d89b29251b33a7e7d006ce86447b2cfd66db5e5ded4e5cd0340585c"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eaeed7abfb5d64c539e2db173f63631455f1196c37d9d8d873fc316470dfbacd"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e91d635961bec2d8f19dfeb41a539eb94bd073f075ca6dae6c8dc0ee89ad6f91"}, + {file = "aiohttp-3.8.5-cp39-cp39-win32.whl", hash = "sha256:00ad4b6f185ec67f3e6562e8a1d2b69660be43070bd0ef6fcec5211154c7df67"}, + {file = "aiohttp-3.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:c0a9034379a37ae42dea7ac1e048352d96286626251862e448933c0f59cbd79c"}, + {file = "aiohttp-3.8.5.tar.gz", hash = "sha256:b9552ec52cc147dbf1944ac7ac98af7602e51ea2dcd076ed194ca3c0d1c7d0bc"}, +] [package.dependencies] aiosignal = ">=1.1.2" @@ -53,10 +156,26 @@ description = "aiosignal: a list of registered asynchronous callbacks" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "annotated-types" +version = "0.5.0" +description = "Reusable constraint types to use with typing.Annotated" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, + {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, +] + [[package]] name = "appnope" version = "0.1.3" @@ -64,6 +183,10 @@ description = "Disable App Nap on macOS >= 10.9" category = "dev" optional = false python-versions = "*" +files = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] [[package]] name = "argcomplete" @@ -72,6 +195,10 @@ description = "Bash tab completion for argparse" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "argcomplete-2.1.2-py3-none-any.whl", hash = "sha256:4ba9cdaa28c361d251edce884cd50b4b1215d65cdc881bd204426cdde9f52731"}, + {file = "argcomplete-2.1.2.tar.gz", hash = "sha256:fc82ef070c607b1559b5c720529d63b54d9dcf2dcfc2632b10e6372314a34457"}, +] [package.extras] lint = ["flake8", "mypy"] @@ -79,11 +206,15 @@ test = ["coverage", "flake8", "mypy", "pexpect", "wheel"] [[package]] name = "astroid" -version = "2.15.4" +version = "2.15.6" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.7.2" +files = [ + {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, + {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, +] [package.dependencies] lazy-object-proxy = ">=1.4.0" @@ -100,6 +231,10 @@ description = "Annotate AST trees with source code positions" category = "dev" optional = false python-versions = "*" +files = [ + {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, + {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, +] [package.dependencies] six = "*" @@ -107,18 +242,6 @@ six = "*" [package.extras] test = ["astroid", "pytest"] -[[package]] -name = "astunparse" -version = "1.6.3" -description = "An AST unparser for Python" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -six = ">=1.6.1,<2.0" -wheel = ">=0.23.0,<1.0" - [[package]] name = "asv" version = "0.6.0" @@ -126,6 +249,9 @@ description = "Airspeed Velocity: A simple Python history benchmarking tool" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "asv-0.6.0.tar.gz", hash = "sha256:9afce3008094209b7e87b7b880bc6b8f2da303fdc6dd665c7be9f1057ecd5753"}, +] [package.dependencies] asv-runner = ">=v0.0.9" @@ -148,17 +274,25 @@ description = "Core Python benchmark code for ASV" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "asv_runner-0.0.9-py3-none-any.whl", hash = "sha256:ef655b451fbe6805b7981ded72d8ac38a8158fa37c770140e1bc6e992e96e5bb"}, + {file = "asv_runner-0.0.9.tar.gz", hash = "sha256:4531cf5677bb19e5bd91d9789378b057037bd17e0d9043621b7ede9eaac88f97"}, +] [package.extras] docs = ["furo", "myst-parser (>=2)", "sphinx", "sphinx-autobuild", "sphinx-autodoc2 (>=0.4.2)", "sphinx-contributors", "sphinx-copybutton", "sphinx-design", "sphinxcontrib-spelling"] [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] [[package]] name = "attrs" @@ -167,6 +301,10 @@ description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] @@ -175,6 +313,18 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[[package]] +name = "babel" +version = "2.12.1" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, + {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, +] + [[package]] name = "backcall" version = "0.2.0" @@ -182,6 +332,10 @@ description = "Specifications for callback functions passed in to an API" category = "dev" optional = false python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] [[package]] name = "beartype" @@ -190,6 +344,10 @@ description = "Unbearably fast runtime type checking in pure Python." category = "main" optional = false python-versions = ">=3.7.0" +files = [ + {file = "beartype-0.13.1-py3-none-any.whl", hash = "sha256:c3097b487e57bc278f1b55da8863b704b2a786c46483a6d3df39ab6fe2523d80"}, + {file = "beartype-0.13.1.tar.gz", hash = "sha256:2903947a8a1eb6030264e30108aa72cb1a805cfc9050c0f4014c4aed3a17a00b"}, +] [package.extras] all = ["typing-extensions (>=3.10.0.0)"] @@ -205,6 +363,10 @@ description = "Screen-scraping library" category = "dev" optional = false python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] [package.dependencies] soupsieve = ">1.2" @@ -215,11 +377,35 @@ lxml = ["lxml"] [[package]] name = "black" -version = "23.3.0" +version = "23.7.0" description = "The uncompromising code formatter." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, + {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, + {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, + {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, + {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, + {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, + {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, + {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, + {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, + {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, + {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, +] [package.dependencies] click = ">=8.0.0" @@ -228,7 +414,6 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -243,6 +428,10 @@ description = "Flexible and fast inference in Python" category = "dev" optional = false python-versions = "*" +files = [ + {file = "blackjax-0.9.6-py3-none-any.whl", hash = "sha256:d1c20dd15a63944a7b5c835bac4900aadf8630bedb0d7e51ab7fc63255eb0dd7"}, + {file = "blackjax-0.9.6.tar.gz", hash = "sha256:fb708f183d714750feb475fb87b8162fc1641309f30ee42fd38a5dec82733868"}, +] [package.dependencies] fastprogress = ">=0.2.0" @@ -257,6 +446,10 @@ description = "An easy safelist-based HTML-sanitizing tool." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, + {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, +] [package.dependencies] six = ">=1.9.0" @@ -265,21 +458,17 @@ webencodings = "*" [package.extras] css = ["tinycss2 (>=1.1.0,<1.2)"] -[[package]] -name = "cached-property" -version = "1.5.2" -description = "A decorator for caching properties in classes." -category = "main" -optional = false -python-versions = "*" - [[package]] name = "certifi" -version = "2023.5.7" +version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." category = "dev" 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 = "cffi" @@ -288,50 +477,204 @@ description = "Foreign Function Interface for Python calling C code." category = "dev" optional = false python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] [package.dependencies] pycparser = "*" [[package]] name = "cfgv" -version = "3.3.1" +version = "3.4.0" description = "Validate configuration and produce human readable error messages." category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, +] [[package]] name = "chex" -version = "0.1.7" +version = "0.1.82" description = "Chex: Testing made fun, in JAX!" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "chex-0.1.82-py3-none-any.whl", hash = "sha256:4df8f087e30c3879c15d3765f9081d5996e57682fa1fbaa8a16a1eab6f6eb2d0"}, + {file = "chex-0.1.82.tar.gz", hash = "sha256:a9b151ada0b5c1bc5a8ae572617eb09f2fe4ff110fe1d75045f9083eecf5b2c1"}, +] [package.dependencies] absl-py = ">=0.9.0" -dm-tree = ">=0.1.5" jax = ">=0.4.6" jaxlib = ">=0.1.37" -numpy = ">=1.18.0" +numpy = ">=1.25.0" toolz = ">=0.9.0" -typing-extensions = {version = ">=4.2.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.2.0" [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -343,6 +686,10 @@ description = "An extension module for click to enable registering CLI commands category = "dev" optional = false python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] [package.dependencies] click = ">=4.0" @@ -357,6 +704,10 @@ description = "Click params for commmand line interfaces to GeoJSON" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" +files = [ + {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, + {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, +] [package.dependencies] click = ">=4.0" @@ -371,21 +722,67 @@ description = "Extended pickling support for Python objects" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, + {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, +] [[package]] name = "codespell" -version = "2.2.4" +version = "2.2.5" description = "Codespell" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "codespell-2.2.5-py3-none-any.whl", hash = "sha256:efa037f54b73c84f7bd14ce8e853d5f822cdd6386ef0ff32e957a3919435b9ec"}, + {file = "codespell-2.2.5.tar.gz", hash = "sha256:6d9faddf6eedb692bf80c9a94ec13ab4f5fb585aabae5f3750727148d7b5be56"}, +] [package.extras] -dev = ["Pygments", "build", "chardet", "flake8", "flake8-pyproject", "pytest", "pytest-cov", "pytest-dependency", "tomli"] +dev = ["Pygments", "build", "chardet", "pytest", "pytest-cov", "pytest-dependency", "ruff", "tomli"] hard-encoding-detection = ["chardet"] toml = ["tomli"] types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency"] +[[package]] +name = "cola-ml" +version = "0.0.1" +description = "" +category = "main" +optional = false +python-versions = ">=3.10" +files = [ + {file = "cola-ml-0.0.1.tar.gz", hash = "sha256:8a49733d4979c32199a78147201d3f228ccc613e3a5ff80c85f3dad4c4beab82"}, + {file = "cola_ml-0.0.1-py3-none-any.whl", hash = "sha256:02b1bcf74f6f4cca44a1aa3c4656f50cebb6549c62266a5d19651490a7b27b9d"}, +] + +[package.dependencies] +cola-plum-dispatch = "0.1.1" +scipy = "*" +tqdm = ">=4.38" + +[package.extras] +dev = ["pytest", "pytest-cov"] + +[[package]] +name = "cola-plum-dispatch" +version = "0.1.1" +description = "Multiple dispatch in Python (with additional features for the CoLA library)" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cola_plum_dispatch-0.1.1-py3-none-any.whl", hash = "sha256:cbdc6097495fa7e5f8d688cf1bc4deb1ea96d505eaadcb623b061401e6799d34"}, + {file = "cola_plum_dispatch-0.1.1.tar.gz", hash = "sha256:95a0399da0e310bab97ce057379df5f920b55b6839f2743eabb8db96eb6a0e7f"}, +] + +[package.dependencies] +beartype = "*" + +[package.extras] +dev = ["black (==22.10.0)", "build", "coveralls", "ghp-import", "ipython", "jupyter-book", "numpy", "pre-commit", "pytest (>=6)", "pytest-cov", "tox", "wheel"] + [[package]] name = "colorama" version = "0.4.6" @@ -393,6 +790,10 @@ description = "Cross-platform colored terminal text." category = "main" 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 = "colorlog" @@ -401,6 +802,10 @@ description = "Add colours to the output of Python's logging module." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, +] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -410,14 +815,18 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] [[package]] name = "comm" -version = "0.1.3" +version = "0.1.4" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, + {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, +] [package.dependencies] -traitlets = ">=5.3" +traitlets = ">=4" [package.extras] lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] @@ -426,29 +835,124 @@ typing = ["mypy (>=0.990)"] [[package]] name = "contourpy" -version = "1.0.7" +version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc"}, + {file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3"}, + {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655"}, + {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48"}, + {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, + {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, + {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, + {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, + {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, + {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, + {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e"}, + {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18"}, + {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, + {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, + {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, + {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, + {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, + {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, + {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103"}, + {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70"}, + {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, + {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, + {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, + {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, + {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, + {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, + {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9"}, + {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15"}, + {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, + {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, + {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, + {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, + {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, + {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, + {file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76"}, + {file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027"}, + {file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104"}, + {file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f"}, + {file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21"}, +] [package.dependencies] numpy = ">=1.16" [package.extras] -bokeh = ["bokeh", "chromedriver", "selenium"] +bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx-copybutton"] -mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"] -test = ["Pillow", "matplotlib", "pytest"] -test-no-images = ["pytest"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.2.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "wurlitzer"] [[package]] name = "coverage" -version = "7.2.5" +version = "7.3.0" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, + {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, + {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, + {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, + {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, + {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, + {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, + {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, + {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, + {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, + {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, + {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, + {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -456,6 +960,18 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cssselect" +version = "1.2.0" +description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e"}, + {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, +] + [[package]] name = "cycler" version = "0.11.0" @@ -463,14 +979,38 @@ description = "Composable style cycles" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] [[package]] name = "debugpy" -version = "1.6.7" +version = "1.6.7.post1" description = "An implementation of the Debug Adapter Protocol for Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, + {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, + {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, + {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, + {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, + {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, + {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, +] [[package]] name = "decorator" @@ -479,6 +1019,10 @@ description = "Decorators for Humans" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] [[package]] name = "defusedxml" @@ -487,25 +1031,37 @@ description = "XML bomb protection for Python stdlib modules" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] [[package]] name = "dill" -version = "0.3.6" -description = "serialize all of python" +version = "0.3.7" +description = "serialize all of Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, + {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, +] [package.extras] graph = ["objgraph (>=1.7.2)"] [[package]] name = "distlib" -version = "0.3.6" +version = "0.3.7" description = "Distribution utilities" category = "dev" optional = false python-versions = "*" +files = [ + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, +] [[package]] name = "dm-tree" @@ -514,53 +1070,112 @@ description = "Tree is a library for working with nested data structures." category = "main" optional = false python-versions = "*" - -[[package]] -name = "etils" -version = "1.2.0" -description = "Collection of common python utils" -category = "main" -optional = false -python-versions = ">=3.8" - -[package.extras] -all = ["etils[array-types]", "etils[eapp]", "etils[ecolab]", "etils[edc]", "etils[enp]", "etils[epath]", "etils[epy]", "etils[etqdm]", "etils[etree-dm]", "etils[etree-jax]", "etils[etree-tf]", "etils[etree]"] -array-types = ["etils[enp]"] -dev = ["chex", "optree", "pyink", "pylint (>=2.6.0)", "pytest", "pytest-subtests", "pytest-xdist", "torch"] -eapp = ["absl-py", "etils[epy]", "simple_parsing"] -ecolab = ["etils[enp]", "etils[epy]", "jupyter", "mediapy", "numpy"] -edc = ["etils[epy]", "typing_extensions"] -enp = ["etils[epy]", "numpy"] -epath = ["etils[epy]", "importlib_resources", "typing_extensions", "zipp"] -epy = ["typing_extensions"] -etqdm = ["absl-py", "etils[epy]", "tqdm"] -etree = ["etils[array-types]", "etils[enp]", "etils[epy]", "etils[etqdm]"] -etree-dm = ["dm-tree", "etils[etree]"] -etree-jax = ["etils[etree]", "jax[cpu]"] -etree-tf = ["etils[etree]", "tensorflow"] -lazy-imports = ["etils[ecolab]"] - -[[package]] -name = "exceptiongroup" -version = "1.1.1" -description = "Backport of PEP 654 (exception groups)" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] +files = [ + {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, + {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, + {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, + {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, + {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, + {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, + {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, +] + +[[package]] +name = "etils" +version = "1.4.1" +description = "Collection of common python utils" +category = "main" +optional = false +python-versions = ">=3.9" +files = [ + {file = "etils-1.4.1-py3-none-any.whl", hash = "sha256:9134111a01872af7014cf3e8ee7496484abdc94fc5ce992800dd989545dcfe2c"}, + {file = "etils-1.4.1.tar.gz", hash = "sha256:53193b57b28ff14c4ee2b27fca1d09c4c1356ceb9324b416e9d9c2eef5f6dfdb"}, +] + +[package.dependencies] +importlib_resources = {version = "*", optional = true, markers = "extra == \"epath\""} +typing_extensions = {version = "*", optional = true, markers = "extra == \"epy\""} +zipp = {version = "*", optional = true, markers = "extra == \"epath\""} + +[package.extras] +all = ["etils[array-types]", "etils[eapp]", "etils[ecolab]", "etils[edc]", "etils[enp]", "etils[epath]", "etils[epy]", "etils[etqdm]", "etils[etree-dm]", "etils[etree-jax]", "etils[etree-tf]", "etils[etree]"] +array-types = ["etils[enp]"] +dev = ["chex", "dataclass_array", "optree", "pyink", "pylint (>=2.6.0)", "pytest", "pytest-subtests", "pytest-xdist", "torch"] +docs = ["etils[all,dev]", "sphinx-apitree[ext]"] +eapp = ["absl-py", "etils[epy]", "simple_parsing"] +ecolab = ["etils[enp]", "etils[epy]", "jupyter", "mediapy", "numpy"] +edc = ["etils[epy]"] +enp = ["etils[epy]", "numpy"] +epath = ["etils[epy]", "importlib_resources", "typing_extensions", "zipp"] +epy = ["typing_extensions"] +etqdm = ["absl-py", "etils[epy]", "tqdm"] +etree = ["etils[array-types]", "etils[enp]", "etils[epy]", "etils[etqdm]"] +etree-dm = ["dm-tree", "etils[etree]"] +etree-jax = ["etils[etree]", "jax[cpu]"] +etree-tf = ["etils[etree]", "tensorflow"] +lazy-imports = ["etils[ecolab]"] + +[[package]] +name = "exceptiongroup" +version = "1.1.3" +description = "Backport of PEP 654 (exception groups)" +category = "dev" +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 = "execnet" -version = "1.9.0" +version = "2.0.2" description = "execnet: rapid multi-Python deployment" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" +files = [ + {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, + {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, +] [package.extras] -testing = ["pre-commit"] +testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "executing" @@ -569,17 +1184,25 @@ description = "Get the currently executing AST node of a frame, and other inform category = "dev" optional = false python-versions = "*" +files = [ + {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, + {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, +] [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.16.3" +version = "2.18.0" description = "Fastest Python implementation of JSON schema" category = "dev" optional = false python-versions = "*" +files = [ + {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, + {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, +] [package.extras] devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] @@ -591,26 +1214,56 @@ description = "A nested progress with plotting options for fastai" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "fastprogress-1.0.3-py3-none-any.whl", hash = "sha256:6dfea88f7a4717b0a8d6ee2048beae5dbed369f932a368c5dd9caff34796f7c5"}, + {file = "fastprogress-1.0.3.tar.gz", hash = "sha256:7a17d2b438890f838c048eefce32c4ded47197ecc8ea042cecc33d3deb8022f5"}, +] [[package]] name = "filelock" -version = "3.12.0" +version = "3.12.2" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, + {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, +] [package.extras] -docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] [[package]] name = "fiona" -version = "1.9.3" +version = "1.9.4.post1" description = "Fiona reads and writes spatial data files" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "Fiona-1.9.4.post1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:d6483a20037db2209c8e9a0c6f1e552f807d03c8f42ed0c865ab500945a37c4d"}, + {file = "Fiona-1.9.4.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dbe158947099a83ad16f9acd3a21f50ff01114c64e2de67805e382e6b6e0083a"}, + {file = "Fiona-1.9.4.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2c7b09eecee3bb074ef8aa518cd6ab30eb663c6fdd0eff3c88d454a9746eaa"}, + {file = "Fiona-1.9.4.post1-cp310-cp310-win_amd64.whl", hash = "sha256:1da8b954f6f222c3c782bc285586ea8dd9d7e55e1bc7861da9cd772bca671660"}, + {file = "Fiona-1.9.4.post1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c671d8832287cda397621d79c5a635d52e4631f33a8f0e6fdc732a79a93cb96c"}, + {file = "Fiona-1.9.4.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b633a2e550e083805c638d2ab8059c283ca112aaea8241e170c012d2ee0aa905"}, + {file = "Fiona-1.9.4.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1faa625d5202b8403471bbc9f9c96b1bf9099cfcb0ee02a80a3641d3d02383e"}, + {file = "Fiona-1.9.4.post1-cp311-cp311-win_amd64.whl", hash = "sha256:39baf11ff0e4318397e2b2197de427b4eebdc49d4a9a7c1366f8a7ed682978a4"}, + {file = "Fiona-1.9.4.post1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d93c993265f6378b23f47708c83bddb3377ca6814a1f0b5a0ae0bee9c8d72cf8"}, + {file = "Fiona-1.9.4.post1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:b0387cae39e27f338fd948b3b50b6e6ce198cc4cec257fc91660849697c69dc3"}, + {file = "Fiona-1.9.4.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:450561d308d3ce7c7e30294822b1de3f4f942033b703ddd4a91a7f7f5f506ca0"}, + {file = "Fiona-1.9.4.post1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71b023ef5248ebfa5524e7a875033f7db3bbfaf634b1b5c1ae36958d1eb82083"}, + {file = "Fiona-1.9.4.post1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74511d3755695d75cea0f4ff6f5e0c6c5d5be8e0d46dafff124c6a219e99b1eb"}, + {file = "Fiona-1.9.4.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:285f3dd4f96aa0a3955ed469f0543375b20989731b2dddc85124453f11ac62bc"}, + {file = "Fiona-1.9.4.post1-cp38-cp38-win_amd64.whl", hash = "sha256:a670ea4262cb9140445bcfc97cbfd2f508a058be342f4a97e966b8ce7696601f"}, + {file = "Fiona-1.9.4.post1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:ea7c44c15b3a653452b9b3173181490b7afc5f153b0473c145c43c0fbf90448b"}, + {file = "Fiona-1.9.4.post1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7bfb1f49e0e53f6cd7ad64ae809d72646266b37a7b9881205977408b443a8d79"}, + {file = "Fiona-1.9.4.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a585002a6385cc8ab0f66ddf3caf18711f531901906abd011a67a0cc89ab7b0"}, + {file = "Fiona-1.9.4.post1-cp39-cp39-win_amd64.whl", hash = "sha256:f5da66b723a876142937e683431bbaa5c3d81bb2ed3ec98941271bc99b7f8cd0"}, + {file = "Fiona-1.9.4.post1.tar.gz", hash = "sha256:5679d3f7e0d513035eb72e59527bb90486859af4405755dfc739138633106120"}, +] [package.dependencies] attrs = ">=19.2.0" @@ -618,8 +1271,7 @@ certifi = "*" click = ">=8.0,<9.0" click-plugins = ">=1.0" cligj = ">=0.5" -importlib-metadata = {version = "*", markers = "python_version < \"3.10\""} -munch = ">=2.3.2" +six = "*" [package.extras] all = ["Fiona[calc,s3,test]"] @@ -629,11 +1281,15 @@ test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] [[package]] name = "flax" -version = "0.6.10" +version = "0.6.11" description = "Flax: A neural network library for JAX designed for flexibility" category = "dev" optional = false python-versions = "*" +files = [ + {file = "flax-0.6.11-py3-none-any.whl", hash = "sha256:3ce6843ed47a35abfd86a7eb47db3934a156d08d6513dc8dcb58d461b0dd6f39"}, + {file = "flax-0.6.11.tar.gz", hash = "sha256:ecedf179ceb16c0b511982a293834bb13086168dce1dff697ac083efa818fc72"}, +] [package.dependencies] jax = ">=0.4.2" @@ -652,11 +1308,47 @@ testing = ["atari-py (==0.2.5)", "clu", "einops", "gym (==0.18.3)", "jaxlib", "j [[package]] name = "fonttools" -version = "4.39.4" +version = "4.42.1" description = "Tools to manipulate font files" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c"}, + {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760"}, + {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b"}, + {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa"}, + {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff"}, + {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd"}, + {file = "fonttools-4.42.1-cp310-cp310-win32.whl", hash = "sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca"}, + {file = "fonttools-4.42.1-cp310-cp310-win_amd64.whl", hash = "sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8"}, + {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5"}, + {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71"}, + {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e"}, + {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341"}, + {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35"}, + {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861"}, + {file = "fonttools-4.42.1-cp311-cp311-win32.whl", hash = "sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a"}, + {file = "fonttools-4.42.1-cp311-cp311-win_amd64.whl", hash = "sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c"}, + {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b"}, + {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0"}, + {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868"}, + {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40"}, + {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d"}, + {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4"}, + {file = "fonttools-4.42.1-cp38-cp38-win32.whl", hash = "sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d"}, + {file = "fonttools-4.42.1-cp38-cp38-win_amd64.whl", hash = "sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd"}, + {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec"}, + {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136"}, + {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360"}, + {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf"}, + {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249"}, + {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967"}, + {file = "fonttools-4.42.1-cp39-cp39-win32.whl", hash = "sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64"}, + {file = "fonttools-4.42.1-cp39-cp39-win_amd64.whl", hash = "sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b"}, + {file = "fonttools-4.42.1-py3-none-any.whl", hash = "sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853"}, + {file = "fonttools-4.42.1.tar.gz", hash = "sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d"}, +] [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)"] @@ -674,19 +1366,86 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "frozenlist" -version = "1.3.3" +version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, + {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, + {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, + {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, + {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, + {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, + {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, + {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, + {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, + {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, +] [[package]] name = "fsspec" -version = "2023.5.0" +version = "2023.6.0" description = "File-system specification" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.6.0-py3-none-any.whl", hash = "sha256:1cbad1faef3e391fba6dc005ae9b5bdcbf43005c9167ce78c915549c352c869a"}, + {file = "fsspec-2023.6.0.tar.gz", hash = "sha256:d0b2f935446169753e7a5c5c55681c54ea91996cc67be93c39a154fb3a2742af"}, +] [package.extras] abfs = ["adlfs"] @@ -719,6 +1478,10 @@ description = "Python AST that abstracts the underlying Python version" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "gast-0.5.4-py3-none-any.whl", hash = "sha256:6fc4fa5fa10b72fb8aab4ae58bcb023058386e67b6fa2e3e34cec5c769360316"}, + {file = "gast-0.5.4.tar.gz", hash = "sha256:9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97"}, +] [[package]] name = "geopandas" @@ -727,6 +1490,10 @@ description = "Geographic pandas extensions" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "geopandas-0.12.2-py3-none-any.whl", hash = "sha256:0a470e4bf6f5367e6fd83ab6b40405e0b805c8174665bbcb7c4077ed90202912"}, + {file = "geopandas-0.12.2.tar.gz", hash = "sha256:0acdacddefa176525e4da6d9aeeece225da26055c4becdc6e97cf40fa97c27f4"}, +] [package.dependencies] fiona = ">=1.8" @@ -742,6 +1509,10 @@ description = "Copy your docs directly to the gh-pages branch." category = "dev" optional = false python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] [package.dependencies] python-dateutil = ">=2.8.1" @@ -756,39 +1527,55 @@ description = "Git Object Database" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, + {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, +] [package.dependencies] smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.31" +version = "3.1.32" description = "GitPython is a Python library used to interact with Git repositories" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.32-py3-none-any.whl", hash = "sha256:e3d59b1c2c6ebb9dfa7a184daf3b6dd4914237e7488a1730a6d8f6f5d0b4187f"}, + {file = "GitPython-3.1.32.tar.gz", hash = "sha256:8d9b8cb1e80b9735e8717c9362079d3ce4c6e5ddeebedd0361b228c3a67a62f6"}, +] [package.dependencies] gitdb = ">=4.0.1,<5" [[package]] name = "griffe" -version = "0.27.4" +version = "0.35.1" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "griffe-0.35.1-py3-none-any.whl", hash = "sha256:ff580073a71793cc58ed1fad696aee49c4bd9e637d3e0cde5b39a269ad8e59e4"}, + {file = "griffe-0.35.1.tar.gz", hash = "sha256:1e3bf605344ab32fe2729161bb4f7761996684f838dfd5a7c60af03a0b20375f"}, +] [package.dependencies] colorama = ">=0.4" [[package]] name = "identify" -version = "2.5.24" +version = "2.5.27" description = "File identification library for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "identify-2.5.27-py2.py3-none-any.whl", hash = "sha256:fdb527b2dfe24602809b2201e033c2a113d7bdf716db3ca8e3243f735dcecaba"}, + {file = "identify-2.5.27.tar.gz", hash = "sha256:287b75b04a0e22d727bc9a41f0d4f3c1bcada97490fa6eabb5b28f0e9097e733"}, +] [package.extras] license = ["ukkonen"] @@ -800,14 +1587,22 @@ description = "Internationalized Domain Names in Applications (IDNA)" category = "dev" 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 = "importlib-metadata" -version = "6.6.0" +version = "6.8.0" description = "Read metadata from Python packages" -category = "main" +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] [package.dependencies] zipp = ">=0.5" @@ -815,22 +1610,23 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" -version = "5.12.0" +version = "6.0.1" description = "Read resources from Python packages" category = "main" optional = false -python-versions = ">=3.7" - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, + {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, +] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [[package]] name = "iniconfig" @@ -839,6 +1635,10 @@ description = "brain-dead simple config-ini parsing" category = "dev" 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 = "interrogate" @@ -847,6 +1647,10 @@ description = "Interrogate a codebase for docstring coverage." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "interrogate-1.5.0-py3-none-any.whl", hash = "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a"}, + {file = "interrogate-1.5.0.tar.gz", hash = "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c"}, +] [package.dependencies] attrs = "*" @@ -864,11 +1668,15 @@ tests = ["pytest", "pytest-cov", "pytest-mock"] [[package]] name = "ipykernel" -version = "6.23.0" +version = "6.25.1" description = "IPython Kernel for Jupyter" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.25.1-py3-none-any.whl", hash = "sha256:c8a2430b357073b37c76c21c52184db42f6b4b0e438e1eb7df3c4440d120497c"}, + {file = "ipykernel-6.25.1.tar.gz", hash = "sha256:050391364c0977e768e354bdb60cbbfbee7cbb943b1af1618382021136ffd42f"}, +] [package.dependencies] appnope = {version = "*", markers = "platform_system == \"Darwin\""} @@ -894,11 +1702,15 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.12.2" +version = "8.14.0" description = "IPython: Productive Interactive Computing" category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "ipython-8.14.0-py3-none-any.whl", hash = "sha256:248aca623f5c99a6635bc3857677b7320b9b8039f99f070ee0d20a5ca5a8e6bf"}, + {file = "ipython-8.14.0.tar.gz", hash = "sha256:1d197b907b6ba441b692c48cf2a3a2de280dc0ac91a3405b39349a50272ca0a1"}, +] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -913,7 +1725,6 @@ prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] @@ -930,14 +1741,18 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa [[package]] name = "ipywidgets" -version = "8.0.6" +version = "8.1.0" description = "Jupyter interactive widgets" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "ipywidgets-8.1.0-py3-none-any.whl", hash = "sha256:6c8396cc7b8c95dfb4e9ab0054f48c002f045e7e5d7ae523f559d64e525a98ab"}, + {file = "ipywidgets-8.1.0.tar.gz", hash = "sha256:ce97dd90525b3066fd00094690964e7eac14cf9b7745d35565b5eeac20cce687"}, +] [package.dependencies] -ipykernel = ">=4.5.1" +comm = ">=0.1.3" ipython = ">=6.1.0" jupyterlab-widgets = ">=3.0.7,<3.1.0" traitlets = ">=4.3.1" @@ -953,6 +1768,10 @@ description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] [package.extras] colors = ["colorama (>=0.4.3)"] @@ -962,43 +1781,59 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jax" -version = "0.4.13" +version = "0.4.14" description = "Differentiate, compile, and transform Numpy code." category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "jax-0.4.14.tar.gz", hash = "sha256:18fed3881f26e8b13c8cb46eeeea3dba9eb4d48e3714d8e8f2304dd6e237083d"}, +] [package.dependencies] -importlib_metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} -ml_dtypes = ">=0.1.0" -numpy = ">=1.21" +ml_dtypes = ">=0.2.0" +numpy = ">=1.22" opt_einsum = "*" scipy = ">=1.7" [package.extras] australis = ["protobuf (>=3.13,<4)"] -ci = ["jaxlib (==0.4.12)"] -cpu = ["jaxlib (==0.4.13)"] -cuda = ["jaxlib (==0.4.13+cuda11.cudnn86)"] -cuda11-cudnn86 = ["jaxlib (==0.4.13+cuda11.cudnn86)"] -cuda11-local = ["jaxlib (==0.4.13+cuda11.cudnn86)"] -cuda11-pip = ["jaxlib (==0.4.13+cuda11.cudnn86)", "nvidia-cublas-cu11 (>=11.11)", "nvidia-cuda-cupti-cu11 (>=11.8)", "nvidia-cuda-nvcc-cu11 (>=11.8)", "nvidia-cuda-runtime-cu11 (>=11.8)", "nvidia-cudnn-cu11 (>=8.8)", "nvidia-cufft-cu11 (>=10.9)", "nvidia-cusolver-cu11 (>=11.4)", "nvidia-cusparse-cu11 (>=11.7)"] -cuda12-local = ["jaxlib (==0.4.13+cuda12.cudnn89)"] -cuda12-pip = ["jaxlib (==0.4.13+cuda12.cudnn89)", "nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc-cu12", "nvidia-cuda-runtime-cu12", "nvidia-cudnn-cu12 (>=8.9)", "nvidia-cufft-cu12", "nvidia-cusolver-cu12", "nvidia-cusparse-cu12"] +ci = ["jaxlib (==0.4.13)"] +cpu = ["jaxlib (==0.4.14)"] +cuda = ["jaxlib (==0.4.14+cuda11.cudnn86)"] +cuda11-cudnn86 = ["jaxlib (==0.4.14+cuda11.cudnn86)"] +cuda11-local = ["jaxlib (==0.4.14+cuda11.cudnn86)"] +cuda11-pip = ["jaxlib (==0.4.14+cuda11.cudnn86)", "nvidia-cublas-cu11 (>=11.11)", "nvidia-cuda-cupti-cu11 (>=11.8)", "nvidia-cuda-nvcc-cu11 (>=11.8)", "nvidia-cuda-runtime-cu11 (>=11.8)", "nvidia-cudnn-cu11 (>=8.8)", "nvidia-cufft-cu11 (>=10.9)", "nvidia-cusolver-cu11 (>=11.4)", "nvidia-cusparse-cu11 (>=11.7)"] +cuda12-local = ["jaxlib (==0.4.14+cuda12.cudnn89)"] +cuda12-pip = ["jaxlib (==0.4.14+cuda12.cudnn89)", "nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc-cu12", "nvidia-cuda-runtime-cu12", "nvidia-cudnn-cu12 (>=8.9)", "nvidia-cufft-cu12", "nvidia-cusolver-cu12", "nvidia-cusparse-cu12"] minimum-jaxlib = ["jaxlib (==0.4.11)"] -tpu = ["jaxlib (==0.4.13)", "libtpu-nightly (==0.1.dev20230622)"] +tpu = ["jaxlib (==0.4.14)", "libtpu-nightly (==0.1.dev20230727)"] [[package]] name = "jaxlib" -version = "0.4.13" +version = "0.4.14" description = "XLA library for JAX" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "jaxlib-0.4.14-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:843839faa8ac82d80eaddbdb8f1b14808ef7716e806a1f0d2e384f7b890c02c3"}, + {file = "jaxlib-0.4.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2dadf061b1828d64e5ee4ac10fa05a051ab2043f11e77d0b7246f3d005afd053"}, + {file = "jaxlib-0.4.14-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:9f2ca54997ea1de7ed96f56025914237595d8e5b99549218bb8652b15c6f5dff"}, + {file = "jaxlib-0.4.14-cp310-cp310-win_amd64.whl", hash = "sha256:504e478acde687fd3ba8ee0b250fb675e26d92b4063d97435d4ea8c5fec360b3"}, + {file = "jaxlib-0.4.14-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:fb06229143c586bbd05bc932d76aa78c83895c03a1670e267da39f7bc61223e9"}, + {file = "jaxlib-0.4.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b38dae702bb8c1b4b54241bf04acefbada9813e606233e59fbc2a51395f650a"}, + {file = "jaxlib-0.4.14-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:5739b7af01d8765c982fd3e5c462ff3ac63d37d583114df639bdc318deb790cb"}, + {file = "jaxlib-0.4.14-cp311-cp311-win_amd64.whl", hash = "sha256:b03714c869fb78f1166a8a0371a160dd27fc047bee9cfea39c93ad64a0496e35"}, + {file = "jaxlib-0.4.14-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:137763b4321a86a84cde4f2ee6f51d74416ca8f7dd79059ebf88403f779829ba"}, + {file = "jaxlib-0.4.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b934e1dbbe1adf49bdf080197db6681c59c80ad07af5e36968dd69825e79a40e"}, + {file = "jaxlib-0.4.14-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:aacea888b9de76ea3b001f0952ba7ae88a4e40a7ede302344b305bbc8d2f5cde"}, + {file = "jaxlib-0.4.14-cp39-cp39-win_amd64.whl", hash = "sha256:fbd3fb60b3a11585e2db58c340f70a1b51a4a37fadc0c77fbe819677ed75ee78"}, +] [package.dependencies] -ml-dtypes = ">=0.1.0" -numpy = ">=1.21" +ml-dtypes = ">=0.2.0" +numpy = ">=1.22" scipy = ">=1.7" [package.extras] @@ -1007,27 +1842,33 @@ cuda12-pip = ["nvidia-cublas-cu12", "nvidia-cuda-cupti-cu12", "nvidia-cuda-nvcc- [[package]] name = "jaxopt" -version = "0.6" +version = "0.8" description = "Hardware accelerated, batchable and differentiable optimizers in JAX." category = "dev" optional = false python-versions = "*" +files = [ + {file = "jaxopt-0.8-py3-none-any.whl", hash = "sha256:6125cdf68cc266a07cab9d27a5a5f46fec27ac2e8a71b654c17fa4d5f087b113"}, + {file = "jaxopt-0.8.tar.gz", hash = "sha256:2affcb89bf3b43fdc3860dafbdafdd278a4265a3750e8c9ee6a468ea5f4bd374"}, +] [package.dependencies] -absl-py = ">=0.7.0" jax = ">=0.2.18" jaxlib = ">=0.1.69" -matplotlib = ">=2.0.1" numpy = ">=1.18.4" scipy = ">=1.0.0" [[package]] name = "jaxtyping" -version = "0.2.19" +version = "0.2.21" description = "Type annotations and runtime checking for shape and dtype of JAX arrays, and PyTrees." category = "main" optional = false -python-versions = "~=3.8" +python-versions = "~=3.9" +files = [ + {file = "jaxtyping-0.2.21-py3-none-any.whl", hash = "sha256:d94afe0def7df435090f1f699d97c06b8b8cfa04667be8fe9215a33bb0f17980"}, + {file = "jaxtyping-0.2.21.tar.gz", hash = "sha256:316e17b06cefff887cc93769d46b77b926a2b110c65e9a129562736297d515a7"}, +] [package.dependencies] numpy = ">=1.20.0" @@ -1036,18 +1877,22 @@ typing-extensions = ">=3.7.4.1" [[package]] name = "jedi" -version = "0.18.2" +version = "0.19.0" description = "An autocompletion tool for Python that can be used for text editors." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, + {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, +] [package.dependencies] -parso = ">=0.8.0,<0.9.0" +parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] @@ -1057,6 +1902,10 @@ description = "A very fast and expressive template engine." category = "dev" 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" @@ -1066,11 +1915,15 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "joblib" -version = "1.2.0" +version = "1.3.2" description = "Lightweight pipelining with Python functions" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, + {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, +] [[package]] name = "json5" @@ -1079,38 +1932,64 @@ description = "A Python implementation of the JSON5 data format." category = "dev" optional = false python-versions = "*" +files = [ + {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, + {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, +] [package.extras] dev = ["hypothesis"] [[package]] name = "jsonschema" -version = "4.17.3" +version = "4.19.0" description = "An implementation of JSON Schema validation for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, + {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, +] [package.dependencies] -attrs = ">=17.4.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +[[package]] +name = "jsonschema-specifications" +version = "2023.7.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, + {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, +] + +[package.dependencies] +referencing = ">=0.28.0" + [[package]] name = "jupyter-client" -version = "8.2.0" +version = "8.3.0" description = "Jupyter protocol implementation and client libraries" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, + {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, +] [package.dependencies] -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" @@ -1123,11 +2002,15 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.3.0" +version = "5.3.1" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"}, + {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"}, +] [package.dependencies] platformdirs = ">=2.5" @@ -1145,25 +2028,37 @@ description = "Pygments theme using JupyterLab CSS variables" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, +] [[package]] name = "jupyterlab-widgets" -version = "3.0.7" +version = "3.0.8" description = "Jupyter interactive widgets for JupyterLab" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "jupyterlab_widgets-3.0.8-py3-none-any.whl", hash = "sha256:4715912d6ceab839c9db35953c764b3214ebbc9161c809f6e0510168845dfdf5"}, + {file = "jupyterlab_widgets-3.0.8.tar.gz", hash = "sha256:d428ab97b8d87cc7c54cbf37644d6e0f0e662f23876e05fa460a73ec3257252a"}, +] [[package]] name = "jupytext" -version = "1.14.5" +version = "1.15.0" description = "Jupyter notebooks as Markdown documents, Julia, Python or R scripts" category = "dev" optional = false python-versions = "~=3.6" +files = [ + {file = "jupytext-1.15.0-py3-none-any.whl", hash = "sha256:7bb7cf4c0a91f5b1591f7558fa3a6494ac6ccf9810d1aa58565d4d9a2675a4a1"}, + {file = "jupytext-1.15.0.tar.gz", hash = "sha256:290c0a04b0a0a341d7ca87a2992cf407eb83898873baddf0bc48039a5e301ff8"}, +] [package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" +markdown-it-py = ">=1.0.0" mdit-py-plugins = "*" nbformat = "*" pyyaml = "*" @@ -1175,11 +2070,117 @@ toml = ["toml"] [[package]] name = "kiwisolver" -version = "1.4.4" +version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" category = "dev" 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 = "latexcodec" @@ -1188,6 +2189,10 @@ description = "A lexer and codec to work with LaTeX code in Python." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, + {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, +] [package.dependencies] six = ">=1.4.1" @@ -1199,6 +2204,44 @@ description = "A fast and thorough lazy object proxy." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] [[package]] name = "linkify-it-py" @@ -1207,6 +2250,10 @@ description = "Links recognition library with FULL unicode support." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, + {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, +] [package.dependencies] uc-micro-py = "*" @@ -1217,27 +2264,141 @@ dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] doc = ["myst-parser", "sphinx", "sphinx-book-theme"] test = ["coverage", "pytest", "pytest-cov"] +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, + {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + [[package]] name = "markdown" -version = "3.3.7" -description = "Python implementation of Markdown." +version = "3.4.4" +description = "Python implementation of John Gruber's Markdown." category = "dev" optional = false -python-versions = ">=3.6" - -[package.dependencies] -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +python-versions = ">=3.7" +files = [ + {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, + {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, +] [package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] testing = ["coverage", "pyyaml"] [[package]] name = "markdown-it-py" -version = "2.2.0" +version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] [package.dependencies] mdurl = ">=0.1,<1.0" @@ -1249,7 +2410,7 @@ compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0 linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] @@ -1259,40 +2420,154 @@ description = "katex extension for Python Markdown" category = "dev" optional = false python-versions = ">=2.7" +files = [ + {file = "markdown-katex-202112.1034.tar.gz", hash = "sha256:27892f4cdd6763816f00e4187d0475500697c090aba16630ec4803a6564bf810"}, + {file = "markdown_katex-202112.1034-py2.py3-none-any.whl", hash = "sha256:9ccc5b4b37db7592cc3ea113d763fafe9ffd1b1587e2c217d6145e44a10b4f6d"}, +] [package.dependencies] Markdown = {version = ">=3.0", markers = "python_version >= \"3.6\""} pathlib2 = "*" setuptools = "*" +[[package]] +name = "markdown2" +version = "2.4.10" +description = "A fast and complete Python implementation of Markdown" +category = "dev" +optional = false +python-versions = ">=3.5, <4" +files = [ + {file = "markdown2-2.4.10-py2.py3-none-any.whl", hash = "sha256:e6105800483783831f5dc54f827aa5b44eb137ecef5a70293d8ecfbb4109ecc6"}, + {file = "markdown2-2.4.10.tar.gz", hash = "sha256:cdba126d90dc3aef6f4070ac342f974d63f415678959329cc7909f96cc235d72"}, +] + +[package.extras] +all = ["pygments (>=2.7.3)", "wavedrom"] +code-syntax-highlighting = ["pygments (>=2.7.3)"] +wavedrom = ["wavedrom"] + [[package]] name = "markupsafe" -version = "2.1.2" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" 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-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.7.1" +version = "3.7.2" description = "Python plotting package" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, + {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, + {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, + {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, + {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, + {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, + {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, + {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, + {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, + {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, + {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, + {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, + {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, + {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, + {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, + {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, + {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, + {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, + {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, + {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, + {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, +] [package.dependencies] contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} kiwisolver = ">=1.0.1" numpy = ">=1.20" packaging = ">=20.0" pillow = ">=6.2.0" -pyparsing = ">=2.3.1" +pyparsing = ">=2.3.1,<3.1" python-dateutil = ">=2.7" -setuptools_scm = ">=7" [[package]] name = "matplotlib-inline" @@ -1301,6 +2576,10 @@ description = "Inline Matplotlib backend for Jupyter" category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] [package.dependencies] traitlets = "*" @@ -1312,21 +2591,29 @@ description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] name = "mdit-py-plugins" -version = "0.3.5" +version = "0.4.0" description = "Collection of plugins for markdown-it-py" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "mdit_py_plugins-0.4.0-py3-none-any.whl", hash = "sha256:b51b3bb70691f57f974e257e367107857a93b36f322a9e6d44ca5bf28ec2def9"}, + {file = "mdit_py_plugins-0.4.0.tar.gz", hash = "sha256:d8ab27e9aed6c38aa716819fedfde15ca275715955f8a185a8e1cf90fb1d2c1b"}, +] [package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" +markdown-it-py = ">=1.0.0,<4.0.0" [package.extras] code-style = ["pre-commit"] -rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] +rtd = ["myst-parser", "sphinx-book-theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] @@ -1336,6 +2623,10 @@ description = "Markdown URL utilities" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] [[package]] name = "mdx-truly-sane-lists" @@ -1344,6 +2635,10 @@ description = "Extension for Python-Markdown that makes lists truly sane. Custom category = "dev" optional = false python-versions = "*" +files = [ + {file = "mdx_truly_sane_lists-1.3-py3-none-any.whl", hash = "sha256:b9546a4c40ff8f1ab692f77cee4b6bfe8ddf9cccf23f0a24e71f3716fe290a37"}, + {file = "mdx_truly_sane_lists-1.3.tar.gz", hash = "sha256:b661022df7520a1e113af7c355c62216b384c867e4f59fb8ee7ad511e6e77f45"}, +] [package.dependencies] Markdown = ">=2.6" @@ -1355,47 +2650,65 @@ description = "A deep merge function for 🐍." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] [[package]] name = "mistune" -version = "2.0.5" -description = "A sane Markdown parser with useful plugins and renderers" +version = "3.0.1" +description = "A sane and fast Markdown parser with useful plugins and renderers" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"}, + {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"}, +] [[package]] name = "mkdocs" -version = "1.4.3" +version = "1.5.2" description = "Project documentation with Markdown." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"}, + {file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"}, +] [package.dependencies] click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" -markdown = ">=3.2.1,<3.4" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] [[package]] name = "mkdocs-autorefs" -version = "0.4.1" +version = "0.5.0" description = "Automatically link across pages in MkDocs." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "mkdocs_autorefs-0.5.0-py3-none-any.whl", hash = "sha256:7930fcb8ac1249f10e683967aeaddc0af49d90702af111a5e390e8b20b3d97ff"}, + {file = "mkdocs_autorefs-0.5.0.tar.gz", hash = "sha256:9a5054a94c08d28855cfab967ada10ed5be76e2bfad642302a610b252c3274c0"}, +] [package.dependencies] Markdown = ">=3.3" @@ -1403,11 +2716,14 @@ mkdocs = ">=1.1" [[package]] name = "mkdocs-bibtex" -version = "2.8.16" +version = "2.11.0" description = "An MkDocs plugin that enables managing citations with BibTex" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mkdocs-bibtex-2.11.0.tar.gz", hash = "sha256:9ed78e1e7cfc8cd6f3f5ca75641dbcea8a011c36dbefcde041e36f8e6d0ed10f"}, +] [package.dependencies] mkdocs = ">=1" @@ -1423,30 +2739,43 @@ description = "MkDocs plugin to programmatically generate documentation pages du category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea"}, + {file = "mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc"}, +] [package.dependencies] mkdocs = ">=1.0.3" [[package]] name = "mkdocs-git-authors-plugin" -version = "0.7.0" +version = "0.7.2" description = "Mkdocs plugin to display git authors of a page" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "mkdocs-git-authors-plugin-0.7.2.tar.gz", hash = "sha256:f541730e4cabdafa0ac758c94d28ba5e8ddca4c859e5de4c89f1226cb6ccd0ad"}, + {file = "mkdocs_git_authors_plugin-0.7.2-py3-none-any.whl", hash = "sha256:c8a2784a867db79ad3b477a96ee96875d17b09192b6d3be71f08df25afff76c4"}, +] [package.dependencies] mkdocs = ">=1.0" [[package]] name = "mkdocs-jupyter" -version = "0.24.1" +version = "0.24.2" description = "Use Jupyter in mkdocs websites" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_jupyter-0.24.2-py3-none-any.whl", hash = "sha256:5295a34b1d0bd0a7688a857323eaf0319d83c8a14179b2651709b8ced6eae7db"}, + {file = "mkdocs_jupyter-0.24.2.tar.gz", hash = "sha256:5e0c109d535d48797230719b6941f4d08de95a7a3c95bf158662c412fc15cb2e"}, +] [package.dependencies] +ipykernel = ">6.0.0,<7.0.0" jupytext = ">1.13.8,<2" mkdocs = ">=1.4.0,<2" mkdocs-material = ">9.0.0" @@ -1454,7 +2783,7 @@ nbconvert = ">=7.2.9,<8" pygments = ">2.12.0" [package.extras] -test = ["pytest", "pytest-cov"] +test = ["coverage[toml]", "pymdown-extensions", "pytest", "pytest-cov"] [[package]] name = "mkdocs-literate-nav" @@ -1463,26 +2792,38 @@ description = "MkDocs plugin to specify the navigation in Markdown instead of YA category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_literate_nav-0.6.0-py3-none-any.whl", hash = "sha256:8c1b84714e5974da5e44e011ec0069275ae7647270c13a679662cf6ffce675a4"}, + {file = "mkdocs_literate_nav-0.6.0.tar.gz", hash = "sha256:81ccbea18163ae8e10bd0bd39237fe70c32a1f2dff6c170779f5d52dd98a0470"}, +] [package.dependencies] mkdocs = ">=1.0.3" [[package]] name = "mkdocs-material" -version = "9.1.11" +version = "9.2.4" description = "Documentation that simply works" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_material-9.2.4-py3-none-any.whl", hash = "sha256:2df876367625ff5e0f7112bc19a57521ed21ce9a2b85656baf9bb7f5dc3cb987"}, + {file = "mkdocs_material-9.2.4.tar.gz", hash = "sha256:25008187b89fc376cb4ed2312b1fea4121bf2bd956442f38afdc6b4dcc21c57d"}, +] [package.dependencies] +babel = ">=2.10.3" colorama = ">=0.4" jinja2 = ">=3.0" +lxml = ">=4.6" markdown = ">=3.2" -mkdocs = ">=1.4.2" +mkdocs = ">=1.5.2" mkdocs-material-extensions = ">=1.1" +paginate = ">=0.5.6" pygments = ">=2.14" pymdown-extensions = ">=9.9.1" +readtime = ">=2.0" regex = ">=2022.4.24" requests = ">=2.26" @@ -1493,6 +2834,10 @@ description = "Extension pack for Python Markdown and MkDocs Material." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, + {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, +] [[package]] name = "mkdocstrings" @@ -1501,6 +2846,10 @@ description = "Automatic documentation from sources, for MkDocs." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mkdocstrings-0.21.2-py3-none-any.whl", hash = "sha256:949ef8da92df9d692ca07be50616459a6b536083a25520fd54b00e8814ce019b"}, + {file = "mkdocstrings-0.21.2.tar.gz", hash = "sha256:304e56a2e90595708a38a13a278e538a67ad82052dd5c8b71f77a604a4f3d911"}, +] [package.dependencies] Jinja2 = ">=2.11.1" @@ -1510,7 +2859,6 @@ mkdocs = ">=1.2" mkdocs-autorefs = ">=0.3.1" mkdocstrings-python = {version = ">=0.5.2", optional = true, markers = "extra == \"python\""} pymdown-extensions = ">=6.3" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} [package.extras] crystal = ["mkdocstrings-crystal (>=0.3.4)"] @@ -1519,14 +2867,18 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "1.0.0" +version = "1.5.2" description = "A Python handler for mkdocstrings." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings_python-1.5.2-py3-none-any.whl", hash = "sha256:ed37ca6d216986e2ac3530c19c3e7be381d1e3d09ea414e4ff467d6fd2cbd9c1"}, + {file = "mkdocstrings_python-1.5.2.tar.gz", hash = "sha256:81eb4a93bc454a253daf247d1a11397c435d641c64fa165324c17c06170b1dfb"}, +] [package.dependencies] -griffe = ">=0.24" +griffe = ">=0.35" mkdocstrings = ">=0.20" [[package]] @@ -1536,6 +2888,9 @@ description = "Plugin for mkdocs to generate markdown documents from jupyter not category = "dev" optional = false python-versions = "*" +files = [ + {file = "mknotebooks-0.7.1-py3-none-any.whl", hash = "sha256:e2fa000b706683fc56b93adada7190a0da22ad85c4f1bfd5c4468cc3552b78e5"}, +] [package.dependencies] gitpython = "*" @@ -1551,23 +2906,45 @@ description = "" category = "dev" optional = false python-versions = "*" +files = [ + {file = "mktestdocs-0.2.1-py2.py3-none-any.whl", hash = "sha256:55ad757e83227d5ba217eb285b8e44dc490601c4bbef52bc3331fea4510b72ec"}, + {file = "mktestdocs-0.2.1.tar.gz", hash = "sha256:44142b98223f02c7ba4629790d9ee83031fd4d8855577c6fbfc23103421d3872"}, +] [package.extras] test = ["pytest (>=4.0.2)"] [[package]] name = "ml-dtypes" -version = "0.1.0" +version = "0.2.0" description = "" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "ml_dtypes-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df6a76e1c8adf484feb138ed323f9f40a7b6c21788f120f7c78bec20ac37ee81"}, + {file = "ml_dtypes-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc29a0524ef5e23a7fbb8d881bdecabeb3fc1d19d9db61785d077a86cb94fab2"}, + {file = "ml_dtypes-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08c391c2794f2aad358e6f4c70785a9a7b1df980ef4c232b3ccd4f6fe39f719"}, + {file = "ml_dtypes-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:75015818a7fccf99a5e8ed18720cb430f3e71a8838388840f4cdf225c036c983"}, + {file = "ml_dtypes-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e70047ec2c83eaee01afdfdabee2c5b0c133804d90d0f7db4dd903360fcc537c"}, + {file = "ml_dtypes-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36d28b8861a8931695e5a31176cad5ae85f6504906650dea5598fbec06c94606"}, + {file = "ml_dtypes-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e85ba8e24cf48d456e564688e981cf379d4c8e644db0a2f719b78de281bac2ca"}, + {file = "ml_dtypes-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:832a019a1b6db5c4422032ca9940a990fa104eee420f643713241b3a518977fa"}, + {file = "ml_dtypes-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8faaf0897942c8253dd126662776ba45f0a5861968cf0f06d6d465f8a7bc298a"}, + {file = "ml_dtypes-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b984cddbe8173b545a0e3334fe56ea1a5c3eb67c507f60d0cfde1d3fa8f8c2"}, + {file = "ml_dtypes-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:022d5a4ee6be14569c2a9d1549e16f1ec87ca949681d0dca59995445d5fcdd5b"}, + {file = "ml_dtypes-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:50845af3e9a601810751b55091dee6c2562403fa1cb4e0123675cf3a4fc2c17a"}, + {file = "ml_dtypes-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f00c71c8c63e03aff313bc6a7aeaac9a4f1483a921a6ffefa6d4404efd1af3d0"}, + {file = "ml_dtypes-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80d304c836d73f10605c58ccf7789c171cc229bfb678748adfb7cea2510dfd0e"}, + {file = "ml_dtypes-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32107e7fa9f62db9a5281de923861325211dfff87bd23faefb27b303314635ab"}, + {file = "ml_dtypes-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:1749b60348da71fd3c2ab303fdbc1965958dc50775ead41f5669c932a341cafd"}, + {file = "ml_dtypes-0.2.0.tar.gz", hash = "sha256:6488eb642acaaf08d8020f6de0a38acee7ac324c1e6e92ee0c0fea42422cb797"}, +] [package.dependencies] numpy = [ - {version = ">1.20", markers = "python_version <= \"3.9\""}, - {version = ">=1.21.2", markers = "python_version > \"3.9\""}, {version = ">=1.23.3", markers = "python_version > \"3.10\""}, + {version = ">=1.21.2", markers = "python_version > \"3.9\""}, ] [package.extras] @@ -1580,6 +2957,71 @@ description = "MessagePack serializer" category = "main" optional = false python-versions = "*" +files = [ + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, + {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, + {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, + {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, + {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, + {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, + {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, + {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, + {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, + {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, + {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, + {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, + {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, + {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, + {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, + {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, +] [[package]] name = "multidict" @@ -1588,21 +3030,82 @@ description = "multidict implementation" category = "dev" optional = false python-versions = ">=3.7" - -[[package]] -name = "munch" -version = "2.5.0" -description = "A dot-accessible dictionary (a la JavaScript objects)" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -six = "*" - -[package.extras] -testing = ["astroid (>=1.5.3,<1.6.0)", "astroid (>=2.0)", "coverage", "pylint (>=1.7.2,<1.8.0)", "pylint (>=2.3.1,<2.4.0)", "pytest"] -yaml = ["PyYAML (>=5.1.0)"] +files = [ + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, + {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, + {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, + {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, + {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, + {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, + {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, + {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, + {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, + {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, + {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, + {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, + {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, +] [[package]] name = "mypy-extensions" @@ -1611,51 +3114,62 @@ description = "Type system extensions for programs checked with the mypy type ch category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] [[package]] name = "nbclient" -version = "0.7.4" +version = "0.8.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "dev" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, + {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, +] [package.dependencies] jupyter-client = ">=6.1.12" jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" nbformat = ">=5.1" -traitlets = ">=5.3" +traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.4.0" +version = "7.7.4" description = "Converting Jupyter Notebooks" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "nbconvert-7.7.4-py3-none-any.whl", hash = "sha256:ace26f4386d08eb5c55833596a942048c5502a95e05590cb523826a749a40a37"}, + {file = "nbconvert-7.7.4.tar.gz", hash = "sha256:1113d039fa3fc3a846ffa5a3b0a019e85aaa94c566a09fa0c400fb7638e46087"}, +] [package.dependencies] beautifulsoup4 = "*" -bleach = "*" +bleach = "!=5.0.0" defusedxml = "*" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} jinja2 = ">=3.0" jupyter-core = ">=4.7" jupyterlab-pygments = "*" markupsafe = ">=2.0" -mistune = ">=2.0.3,<3" +mistune = ">=2.0.3,<4" nbclient = ">=0.5.0" -nbformat = ">=5.1" +nbformat = ">=5.7" packaging = "*" pandocfilters = ">=1.4.1" pygments = ">=2.4.1" tinycss2 = "*" -traitlets = ">=5.0" +traitlets = ">=5.1" [package.extras] all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] @@ -1663,16 +3177,20 @@ docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sp qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] -webpdf = ["pyppeteer (>=1,<1.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +webpdf = ["playwright"] [[package]] name = "nbformat" -version = "5.8.0" +version = "5.9.2" description = "The Jupyter Notebook format" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, + {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, +] [package.dependencies] fastjsonschema = "*" @@ -1691,17 +3209,25 @@ description = "Strips outputs from Jupyter and IPython notebooks" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "nbstripout-0.6.1-py2.py3-none-any.whl", hash = "sha256:5ff6eb0debbcd656c4a64db8e082a24fabcfc753a9e8c9f6d786971e8f29e110"}, + {file = "nbstripout-0.6.1.tar.gz", hash = "sha256:9065bcdd1488b386e4f3c081ffc1d48f4513a2f8d8bf4d0d9a28208c5dafe9d3"}, +] [package.dependencies] nbformat = "*" [[package]] name = "nest-asyncio" -version = "1.5.6" +version = "1.5.7" description = "Patch asyncio to allow nested event loops" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, + {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, +] [[package]] name = "networkx" @@ -1710,6 +3236,10 @@ description = "Python package for creating and manipulating graphs and networks" category = "dev" 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)"] @@ -1720,11 +3250,15 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "nodeenv" -version = "1.7.0" +version = "1.8.0" description = "Node.js virtual environment builder" category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] [package.dependencies] setuptools = "*" @@ -1736,6 +3270,10 @@ description = "Flexible test automation." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "nox-2022.11.21-py3-none-any.whl", hash = "sha256:0e41a990e290e274cb205a976c4c97ee3c5234441a8132c8c3fd9ea3c22149eb"}, + {file = "nox-2022.11.21.tar.gz", hash = "sha256:e21c31de0711d1274ca585a2c5fde36b1aa962005ba8e9322bf5eeed16dcd684"}, +] [package.dependencies] argcomplete = ">=1.9.4,<3.0" @@ -1748,11 +3286,38 @@ tox-to-nox = ["jinja2", "tox"] [[package]] name = "numpy" -version = "1.24.3" +version = "1.25.2" description = "Fundamental package for array computing in Python" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, + {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, + {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, + {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, + {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, + {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, + {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, + {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, + {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, + {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, + {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, + {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, +] [[package]] name = "opt-einsum" @@ -1761,6 +3326,10 @@ description = "Optimizing numpys einsum function" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, + {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, +] [package.dependencies] numpy = ">=1.7" @@ -1771,11 +3340,15 @@ tests = ["pytest", "pytest-cov", "pytest-pep8"] [[package]] name = "optax" -version = "0.1.5" +version = "0.1.7" description = "A gradient processing and optimisation library in JAX." category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "optax-0.1.7-py3-none-any.whl", hash = "sha256:2b85115f2ae7adafe5fd9abf4b275e53057765361511c8ccc868e70158458494"}, + {file = "optax-0.1.7.tar.gz", hash = "sha256:6a5a848bc5e55e619b187c749fdddc4a5443ea14be85cc769f995779865c110d"}, +] [package.dependencies] absl-py = ">=0.7.1" @@ -1784,30 +3357,39 @@ jax = ">=0.1.55" jaxlib = ">=0.1.37" numpy = ">=1.18.0" +[package.extras] +docs = ["IPython (==7.16.3)", "dm-haiku (==0.0.8)", "docutils (==0.16)", "ipykernel (==5.3.4)", "matplotlib (==3.5.0)", "myst_nb (==0.13.1)", "pandoc (==1.0.2)", "sphinx (==4.5.0)", "sphinx-autodoc-typehints (==1.11.1)", "sphinx-book-theme (==0.3.3)", "sphinxcontrib-bibtex (==2.4.2)", "sphinxcontrib-katex (==0.9.0)"] +dp-accounting = ["absl-py (>=1.0.0)", "attrs (>=21.4.0)", "mpmath (>=1.2.1)", "numpy (>=1.21.4)", "scipy (>=1.7.1)"] +examples = ["dm-haiku (>=0.0.3)", "tensorflow (>=2.4.0)", "tensorflow-datasets (>=4.2.0)"] +test = ["dm-haiku (>=0.0.3)", "dm-tree (>=0.1.7)", "flax (==0.5.3)"] + [[package]] name = "orbax-checkpoint" -version = "0.2.3" +version = "0.3.5" description = "Orbax Checkpoint" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "orbax_checkpoint-0.3.5-py3-none-any.whl", hash = "sha256:5c297b32985a76cacbe22d17057a13a81d968a108a90565000b471f55ee08539"}, + {file = "orbax_checkpoint-0.3.5.tar.gz", hash = "sha256:fb573e132503c6e9dfa5ff17ff22521f326a6bf929002e3d62d0397c617f9775"}, +] [package.dependencies] absl-py = "*" -cached_property = "*" -etils = "*" -importlib_resources = "*" +etils = {version = "*", extras = ["epath", "epy"]} jax = ">=0.4.9" jaxlib = "*" msgpack = "*" nest_asyncio = "*" numpy = "*" +protobuf = "*" pyyaml = "*" tensorstore = ">=0.1.35" typing_extensions = "*" [package.extras] -dev = ["flax", "pytest", "pytest-xdist"] +testing = ["flax", "pytest", "pytest-xdist"] [[package]] name = "packaging" @@ -1816,18 +3398,61 @@ description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] [[package]] -name = "pandas" +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + +[[package]] +name = "pandas" version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, + {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, + {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, + {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, + {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, + {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, + {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, + {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, +] [package.dependencies] numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, ] @@ -1844,6 +3469,10 @@ description = "Utilities for writing pandoc filters in python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, + {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, +] [[package]] name = "parso" @@ -1852,6 +3481,10 @@ description = "A Python Parser" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] [package.extras] qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] @@ -1864,17 +3497,25 @@ description = "Object-oriented filesystem paths" category = "dev" optional = false python-versions = "*" +files = [ + {file = "pathlib2-2.3.7.post1-py2.py3-none-any.whl", hash = "sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b"}, + {file = "pathlib2-2.3.7.post1.tar.gz", hash = "sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641"}, +] [package.dependencies] six = "*" [[package]] name = "pathspec" -version = "0.11.1" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] [[package]] name = "pexpect" @@ -1883,6 +3524,10 @@ description = "Pexpect allows easy control of interactive console applications." category = "dev" optional = false python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] [package.dependencies] ptyprocess = ">=0.5" @@ -1894,27 +3539,81 @@ description = "Tiny 'shelve'-like database with concurrency support" category = "dev" optional = false python-versions = "*" +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] [[package]] name = "pillow" -version = "9.5.0" +version = "10.0.0" description = "Python Imaging Library (Fork)" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, + {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, + {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, + {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, + {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, + {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, + {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, + {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, + {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, + {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, +] [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 = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "planetary-computer" version = "0.5.1" @@ -1922,6 +3621,10 @@ description = "Planetary Computer SDK for Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "planetary-computer-0.5.1.tar.gz", hash = "sha256:a46de4a6bab359a5b691f2059f5dbe842c92b45390b5f1ab465bdf2819008d35"}, + {file = "planetary_computer-0.5.1-py3-none-any.whl", hash = "sha256:87cd7b89a8df33b71aab3a05b390ecedd3830ece1bb3ad33725019db30c9683f"}, +] [package.dependencies] click = ">=7.1" @@ -1938,49 +3641,47 @@ dev = ["black", "flake8", "mypy", "pytest", "responses", "setuptools", "types-re [[package]] name = "platformdirs" -version = "3.5.1" +version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, +] [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +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.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, +] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "plum-dispatch" -version = "2.1.0" -description = "Multiple dispatch in Python" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -beartype = "*" - -[package.extras] -dev = ["black (==22.10.0)", "build", "coveralls", "ghp-import", "ipython", "jupyter-book", "numpy", "pre-commit", "pytest (>=6)", "pytest-cov", "tox", "wheel"] - [[package]] name = "pre-commit" -version = "3.3.1" +version = "3.3.3" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "pre_commit-3.3.3-py2.py3-none-any.whl", hash = "sha256:10badb65d6a38caff29703362271d7dca483d01da88f9d7e05d0b97171c136cb"}, + {file = "pre_commit-3.3.3.tar.gz", hash = "sha256:a2256f489cd913d575c145132ae196fe335da32d91a8294b7afe6622335dd023"}, +] [package.dependencies] cfgv = ">=2.0.0" @@ -1991,15 +3692,42 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.38" +version = "3.0.39" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, + {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, +] [package.dependencies] wcwidth = "*" +[[package]] +name = "protobuf" +version = "4.24.2" +description = "" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "protobuf-4.24.2-cp310-abi3-win32.whl", hash = "sha256:58e12d2c1aa428ece2281cef09bbaa6938b083bcda606db3da4e02e991a0d924"}, + {file = "protobuf-4.24.2-cp310-abi3-win_amd64.whl", hash = "sha256:77700b55ba41144fc64828e02afb41901b42497b8217b558e4a001f18a85f2e3"}, + {file = "protobuf-4.24.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:237b9a50bd3b7307d0d834c1b0eb1a6cd47d3f4c2da840802cd03ea288ae8880"}, + {file = "protobuf-4.24.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:25ae91d21e3ce8d874211110c2f7edd6384816fb44e06b2867afe35139e1fd1c"}, + {file = "protobuf-4.24.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:c00c3c7eb9ad3833806e21e86dca448f46035242a680f81c3fe068ff65e79c74"}, + {file = "protobuf-4.24.2-cp37-cp37m-win32.whl", hash = "sha256:4e69965e7e54de4db989289a9b971a099e626f6167a9351e9d112221fc691bc1"}, + {file = "protobuf-4.24.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c5cdd486af081bf752225b26809d2d0a85e575b80a84cde5172a05bbb1990099"}, + {file = "protobuf-4.24.2-cp38-cp38-win32.whl", hash = "sha256:6bd26c1fa9038b26c5c044ee77e0ecb18463e957fefbaeb81a3feb419313a54e"}, + {file = "protobuf-4.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb7aa97c252279da65584af0456f802bd4b2de429eb945bbc9b3d61a42a8cd16"}, + {file = "protobuf-4.24.2-cp39-cp39-win32.whl", hash = "sha256:2b23bd6e06445699b12f525f3e92a916f2dcf45ffba441026357dea7fa46f42b"}, + {file = "protobuf-4.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:839952e759fc40b5d46be319a265cf94920174d88de31657d5622b5d8d6be5cd"}, + {file = "protobuf-4.24.2-py3-none-any.whl", hash = "sha256:3b7b170d3491ceed33f723bbf2d5a260f8a4e23843799a3906f16ef736ef251e"}, + {file = "protobuf-4.24.2.tar.gz", hash = "sha256:7fda70797ddec31ddfa3576cbdcc3ddbb6b3078b737a1a87ab9136af0570cd6e"}, +] + [[package]] name = "psutil" version = "5.9.5" @@ -2007,6 +3735,22 @@ description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, + {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, + {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, + {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, + {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, + {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, + {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, + {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, +] [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] @@ -2018,6 +3762,10 @@ description = "Run a subprocess in a pseudo terminal" category = "dev" optional = false python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] [[package]] name = "pure-eval" @@ -2026,6 +3774,10 @@ description = "Safely evaluate AST nodes without side effects" category = "dev" optional = false python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] [package.extras] tests = ["pytest"] @@ -2037,6 +3789,10 @@ description = "library with cross-python path, ini-parsing, io, code, log facili category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] [[package]] name = "pybtex" @@ -2045,6 +3801,10 @@ description = "A BibTeX-compatible bibliography processor in Python" category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ + {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, + {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, +] [package.dependencies] latexcodec = ">=1.0.4" @@ -2061,22 +3821,149 @@ description = "C parser in Python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] [[package]] name = "pydantic" -version = "1.10.7" -description = "Data validation and settings management using python type hints" +version = "2.3.0" +description = "Data validation using Python type hints" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pydantic-2.3.0-py3-none-any.whl", hash = "sha256:45b5e446c6dfaad9444819a293b921a40e1db1aa61ea08aede0522529ce90e81"}, + {file = "pydantic-2.3.0.tar.gz", hash = "sha256:1607cc106602284cd4a00882986570472f193fde9cb1259bceeaedb26aa79a6d"}, +] [package.dependencies] -python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.6.3" +typing-extensions = ">=4.6.1" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.6.3" +description = "" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_core-2.6.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:1a0ddaa723c48af27d19f27f1c73bdc615c73686d763388c8683fe34ae777bad"}, + {file = "pydantic_core-2.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5cfde4fab34dd1e3a3f7f3db38182ab6c95e4ea91cf322242ee0be5c2f7e3d2f"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a7027bfc6b108e17c3383959485087d5942e87eb62bbac69829eae9bc1f7"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84e87c16f582f5c753b7f39a71bd6647255512191be2d2dbf49458c4ef024588"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:522a9c4a4d1924facce7270c84b5134c5cabcb01513213662a2e89cf28c1d309"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaafc776e5edc72b3cad1ccedb5fd869cc5c9a591f1213aa9eba31a781be9ac1"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a750a83b2728299ca12e003d73d1264ad0440f60f4fc9cee54acc489249b728"}, + {file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e8b374ef41ad5c461efb7a140ce4730661aadf85958b5c6a3e9cf4e040ff4bb"}, + {file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b594b64e8568cf09ee5c9501ede37066b9fc41d83d58f55b9952e32141256acd"}, + {file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2a20c533cb80466c1d42a43a4521669ccad7cf2967830ac62c2c2f9cece63e7e"}, + {file = "pydantic_core-2.6.3-cp310-none-win32.whl", hash = "sha256:04fe5c0a43dec39aedba0ec9579001061d4653a9b53a1366b113aca4a3c05ca7"}, + {file = "pydantic_core-2.6.3-cp310-none-win_amd64.whl", hash = "sha256:6bf7d610ac8f0065a286002a23bcce241ea8248c71988bda538edcc90e0c39ad"}, + {file = "pydantic_core-2.6.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:6bcc1ad776fffe25ea5c187a028991c031a00ff92d012ca1cc4714087e575973"}, + {file = "pydantic_core-2.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:df14f6332834444b4a37685810216cc8fe1fe91f447332cd56294c984ecbff1c"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b7486d85293f7f0bbc39b34e1d8aa26210b450bbd3d245ec3d732864009819"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a892b5b1871b301ce20d40b037ffbe33d1407a39639c2b05356acfef5536d26a"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:883daa467865e5766931e07eb20f3e8152324f0adf52658f4d302242c12e2c32"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4eb77df2964b64ba190eee00b2312a1fd7a862af8918ec70fc2d6308f76ac64"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce8c84051fa292a5dc54018a40e2a1926fd17980a9422c973e3ebea017aa8da"}, + {file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22134a4453bd59b7d1e895c455fe277af9d9d9fbbcb9dc3f4a97b8693e7e2c9b"}, + {file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:02e1c385095efbd997311d85c6021d32369675c09bcbfff3b69d84e59dc103f6"}, + {file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d79f1f2f7ebdb9b741296b69049ff44aedd95976bfee38eb4848820628a99b50"}, + {file = "pydantic_core-2.6.3-cp311-none-win32.whl", hash = "sha256:430ddd965ffd068dd70ef4e4d74f2c489c3a313adc28e829dd7262cc0d2dd1e8"}, + {file = "pydantic_core-2.6.3-cp311-none-win_amd64.whl", hash = "sha256:84f8bb34fe76c68c9d96b77c60cef093f5e660ef8e43a6cbfcd991017d375950"}, + {file = "pydantic_core-2.6.3-cp311-none-win_arm64.whl", hash = "sha256:5a2a3c9ef904dcdadb550eedf3291ec3f229431b0084666e2c2aa8ff99a103a2"}, + {file = "pydantic_core-2.6.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8421cf496e746cf8d6b677502ed9a0d1e4e956586cd8b221e1312e0841c002d5"}, + {file = "pydantic_core-2.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bb128c30cf1df0ab78166ded1ecf876620fb9aac84d2413e8ea1594b588c735d"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a822f630712817b6ecc09ccc378192ef5ff12e2c9bae97eb5968a6cdf3b862"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:240a015102a0c0cc8114f1cba6444499a8a4d0333e178bc504a5c2196defd456"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f90e5e3afb11268628c89f378f7a1ea3f2fe502a28af4192e30a6cdea1e7d5e"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:340e96c08de1069f3d022a85c2a8c63529fd88709468373b418f4cf2c949fb0e"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1480fa4682e8202b560dcdc9eeec1005f62a15742b813c88cdc01d44e85308e5"}, + {file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f14546403c2a1d11a130b537dda28f07eb6c1805a43dae4617448074fd49c282"}, + {file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a87c54e72aa2ef30189dc74427421e074ab4561cf2bf314589f6af5b37f45e6d"}, + {file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f93255b3e4d64785554e544c1c76cd32f4a354fa79e2eeca5d16ac2e7fdd57aa"}, + {file = "pydantic_core-2.6.3-cp312-none-win32.whl", hash = "sha256:f70dc00a91311a1aea124e5f64569ea44c011b58433981313202c46bccbec0e1"}, + {file = "pydantic_core-2.6.3-cp312-none-win_amd64.whl", hash = "sha256:23470a23614c701b37252618e7851e595060a96a23016f9a084f3f92f5ed5881"}, + {file = "pydantic_core-2.6.3-cp312-none-win_arm64.whl", hash = "sha256:1ac1750df1b4339b543531ce793b8fd5c16660a95d13aecaab26b44ce11775e9"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:a53e3195f134bde03620d87a7e2b2f2046e0e5a8195e66d0f244d6d5b2f6d31b"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:f2969e8f72c6236c51f91fbb79c33821d12a811e2a94b7aa59c65f8dbdfad34a"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:672174480a85386dd2e681cadd7d951471ad0bb028ed744c895f11f9d51b9ebe"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:002d0ea50e17ed982c2d65b480bd975fc41086a5a2f9c924ef8fc54419d1dea3"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ccc13afee44b9006a73d2046068d4df96dc5b333bf3509d9a06d1b42db6d8bf"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:439a0de139556745ae53f9cc9668c6c2053444af940d3ef3ecad95b079bc9987"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63b7545d489422d417a0cae6f9898618669608750fc5e62156957e609e728a5"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b44c42edc07a50a081672e25dfe6022554b47f91e793066a7b601ca290f71e42"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1c721bfc575d57305dd922e6a40a8fe3f762905851d694245807a351ad255c58"}, + {file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5e4a2cf8c4543f37f5dc881de6c190de08096c53986381daebb56a355be5dfe6"}, + {file = "pydantic_core-2.6.3-cp37-none-win32.whl", hash = "sha256:d9b4916b21931b08096efed090327f8fe78e09ae8f5ad44e07f5c72a7eedb51b"}, + {file = "pydantic_core-2.6.3-cp37-none-win_amd64.whl", hash = "sha256:a8acc9dedd304da161eb071cc7ff1326aa5b66aadec9622b2574ad3ffe225525"}, + {file = "pydantic_core-2.6.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:5e9c068f36b9f396399d43bfb6defd4cc99c36215f6ff33ac8b9c14ba15bdf6b"}, + {file = "pydantic_core-2.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e61eae9b31799c32c5f9b7be906be3380e699e74b2db26c227c50a5fc7988698"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85463560c67fc65cd86153a4975d0b720b6d7725cf7ee0b2d291288433fc21b"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9616567800bdc83ce136e5847d41008a1d602213d024207b0ff6cab6753fe645"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e9b65a55bbabda7fccd3500192a79f6e474d8d36e78d1685496aad5f9dbd92c"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f468d520f47807d1eb5d27648393519655eadc578d5dd862d06873cce04c4d1b"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9680dd23055dd874173a3a63a44e7f5a13885a4cfd7e84814be71be24fba83db"}, + {file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a718d56c4d55efcfc63f680f207c9f19c8376e5a8a67773535e6f7e80e93170"}, + {file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8ecbac050856eb6c3046dea655b39216597e373aa8e50e134c0e202f9c47efec"}, + {file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:788be9844a6e5c4612b74512a76b2153f1877cd845410d756841f6c3420230eb"}, + {file = "pydantic_core-2.6.3-cp38-none-win32.whl", hash = "sha256:07a1aec07333bf5adebd8264047d3dc518563d92aca6f2f5b36f505132399efc"}, + {file = "pydantic_core-2.6.3-cp38-none-win_amd64.whl", hash = "sha256:621afe25cc2b3c4ba05fff53525156d5100eb35c6e5a7cf31d66cc9e1963e378"}, + {file = "pydantic_core-2.6.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:813aab5bfb19c98ae370952b6f7190f1e28e565909bfc219a0909db168783465"}, + {file = "pydantic_core-2.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:50555ba3cb58f9861b7a48c493636b996a617db1a72c18da4d7f16d7b1b9952b"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e20f8baedd7d987bd3f8005c146e6bcbda7cdeefc36fad50c66adb2dd2da48"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0a5d7edb76c1c57b95df719af703e796fc8e796447a1da939f97bfa8a918d60"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f06e21ad0b504658a3a9edd3d8530e8cea5723f6ea5d280e8db8efc625b47e49"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea053cefa008fda40f92aab937fb9f183cf8752e41dbc7bc68917884454c6362"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:171a4718860790f66d6c2eda1d95dd1edf64f864d2e9f9115840840cf5b5713f"}, + {file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ed7ceca6aba5331ece96c0e328cd52f0dcf942b8895a1ed2642de50800b79d3"}, + {file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:acafc4368b289a9f291e204d2c4c75908557d4f36bd3ae937914d4529bf62a76"}, + {file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1aa712ba150d5105814e53cb141412217146fedc22621e9acff9236d77d2a5ef"}, + {file = "pydantic_core-2.6.3-cp39-none-win32.whl", hash = "sha256:44b4f937b992394a2e81a5c5ce716f3dcc1237281e81b80c748b2da6dd5cf29a"}, + {file = "pydantic_core-2.6.3-cp39-none-win_amd64.whl", hash = "sha256:9b33bf9658cb29ac1a517c11e865112316d09687d767d7a0e4a63d5c640d1b17"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d7050899026e708fb185e174c63ebc2c4ee7a0c17b0a96ebc50e1f76a231c057"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:99faba727727b2e59129c59542284efebbddade4f0ae6a29c8b8d3e1f437beb7"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fa159b902d22b283b680ef52b532b29554ea2a7fc39bf354064751369e9dbd7"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:046af9cfb5384f3684eeb3f58a48698ddab8dd870b4b3f67f825353a14441418"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:930bfe73e665ebce3f0da2c6d64455098aaa67e1a00323c74dc752627879fc67"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:85cc4d105747d2aa3c5cf3e37dac50141bff779545ba59a095f4a96b0a460e70"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b25afe9d5c4f60dcbbe2b277a79be114e2e65a16598db8abee2a2dcde24f162b"}, + {file = "pydantic_core-2.6.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e49ce7dc9f925e1fb010fc3d555250139df61fa6e5a0a95ce356329602c11ea9"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2dd50d6a1aef0426a1d0199190c6c43ec89812b1f409e7fe44cb0fbf6dfa733c"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6595b0d8c8711e8e1dc389d52648b923b809f68ac1c6f0baa525c6440aa0daa"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ef724a059396751aef71e847178d66ad7fc3fc969a1a40c29f5aac1aa5f8784"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3c8945a105f1589ce8a693753b908815e0748f6279959a4530f6742e1994dcb6"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c8c6660089a25d45333cb9db56bb9e347241a6d7509838dbbd1931d0e19dbc7f"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:692b4ff5c4e828a38716cfa92667661a39886e71136c97b7dac26edef18767f7"}, + {file = "pydantic_core-2.6.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f1a5d8f18877474c80b7711d870db0eeef9442691fcdb00adabfc97e183ee0b0"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3796a6152c545339d3b1652183e786df648ecdf7c4f9347e1d30e6750907f5bb"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b962700962f6e7a6bd77e5f37320cabac24b4c0f76afeac05e9f93cf0c620014"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56ea80269077003eaa59723bac1d8bacd2cd15ae30456f2890811efc1e3d4413"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c0ebbebae71ed1e385f7dfd9b74c1cff09fed24a6df43d326dd7f12339ec34"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:252851b38bad3bfda47b104ffd077d4f9604a10cb06fe09d020016a25107bf98"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6656a0ae383d8cd7cc94e91de4e526407b3726049ce8d7939049cbfa426518c8"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9140ded382a5b04a1c030b593ed9bf3088243a0a8b7fa9f071a5736498c5483"}, + {file = "pydantic_core-2.6.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d38bbcef58220f9c81e42c255ef0bf99735d8f11edef69ab0b499da77105158a"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c9d469204abcca28926cbc28ce98f28e50e488767b084fb3fbdf21af11d3de26"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48c1ed8b02ffea4d5c9c220eda27af02b8149fe58526359b3c07eb391cb353a2"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2b1bfed698fa410ab81982f681f5b1996d3d994ae8073286515ac4d165c2e7"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf9d42a71a4d7a7c1f14f629e5c30eac451a6fc81827d2beefd57d014c006c4a"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4292ca56751aebbe63a84bbfc3b5717abb09b14d4b4442cc43fd7c49a1529efd"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7dc2ce039c7290b4ef64334ec7e6ca6494de6eecc81e21cb4f73b9b39991408c"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:615a31b1629e12445c0e9fc8339b41aaa6cc60bd53bf802d5fe3d2c0cda2ae8d"}, + {file = "pydantic_core-2.6.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1fa1f6312fb84e8c281f32b39affe81984ccd484da6e9d65b3d18c202c666149"}, + {file = "pydantic_core-2.6.3.tar.gz", hash = "sha256:1508f37ba9e3ddc0189e6ff4e2228bd2d3c3a4641cbe8c07177162f76ed696c7"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" @@ -2085,6 +3972,10 @@ description = "Python docstring style checker" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, +] [package.dependencies] snowballstemmer = ">=2.2.0" @@ -2094,25 +3985,33 @@ toml = ["tomli (>=1.2.3)"] [[package]] name = "pygments" -version = "2.15.1" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] [package.extras] plugins = ["importlib-metadata"] [[package]] name = "pylint" -version = "2.17.4" +version = "2.17.5" description = "python code static checker" category = "dev" optional = false python-versions = ">=3.7.2" +files = [ + {file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"}, + {file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"}, +] [package.dependencies] -astroid = ">=2.15.4,<=2.17.0-dev0" +astroid = ">=2.15.6,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, @@ -2123,7 +4022,6 @@ mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] spelling = ["pyenchant (>=3.2,<4.0)"] @@ -2136,6 +4034,10 @@ description = "Extension pack for Python Markdown." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pymdown_extensions-9.11-py3-none-any.whl", hash = "sha256:a499191d8d869f30339de86fcf072a787e86c42b6f16f280f5c2cf174182b7f3"}, + {file = "pymdown_extensions-9.11.tar.gz", hash = "sha256:f7e86c1d3981f23d9dc43294488ecb54abadd05b0be4bf8f0e15efc90f7853ff"}, +] [package.dependencies] markdown = ">=3.2" @@ -2148,6 +4050,10 @@ description = "A development tool to measure, monitor and analyze the memory beh category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"}, + {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, +] [[package]] name = "pypandoc" @@ -2156,6 +4062,10 @@ description = "Thin wrapper for pandoc." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pypandoc-1.11-py3-none-any.whl", hash = "sha256:b260596934e9cfc6513056110a7c8600171d414f90558bf4407e68b209be8007"}, + {file = "pypandoc-1.11.tar.gz", hash = "sha256:7f6d68db0e57e0f6961bec2190897118c4d305fc2d31c22cd16037f22ee084a5"}, +] [[package]] name = "pyparsing" @@ -2164,44 +4074,94 @@ description = "pyparsing module - Classes and methods to define and execute pars category = "dev" optional = false python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] [package.extras] diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyproj" -version = "3.5.0" +version = "3.6.0" description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +files = [ + {file = "pyproj-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e600f6a2771d3b41aeb2cc1efd96771ae9a01451013da1dd48ff272e7c6e34ef"}, + {file = "pyproj-3.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d7f6cd045df29aae960391dfe06a575c110af598f1dea5add8be6ca42332b0f5"}, + {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557e6592855111c84eda176ddf6b130f55d5e2b9cb1c017b8c91b69f37f474f5"}, + {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de6288b6ceabdeeac01abf627c74414822d322d8f55dc8efe4d29dedd27c5719"}, + {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e427ccdbb1763872416549bdfa9fa1f5f169054653c4daf674e71480cc39cf11"}, + {file = "pyproj-3.6.0-cp310-cp310-win32.whl", hash = "sha256:1283d3c1960edbb74828f5f3405b27578a9a27f7766ab6a3956f4bd851f08239"}, + {file = "pyproj-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:9de1aab71234bfd3fd648a1152519b5ee152c43113d7d8ea52590a0140129501"}, + {file = "pyproj-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:00fab048596c17572fa8980014ef117dbb2a445e6f7ba3b9ddfcc683efc598e7"}, + {file = "pyproj-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba5e7c8ddd6ed5a3f9fcf95ea80ba44c931913723de2ece841c94bb38b200c4a"}, + {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08dfc5c9533c78a97afae9d53b99b810a4a8f97c3be9eb2b8f323b726c736403"}, + {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18a8bdb87aeb41b60a2e91d32f623227de3569fb83b4c64b174c3a7c5b0ed3ae"}, + {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfe392dfc0eba2248dc08c976a72f52ff9da2bddfddfd9ff5dcf18e8e88200c7"}, + {file = "pyproj-3.6.0-cp311-cp311-win32.whl", hash = "sha256:78276c6b0c831255c97c56dff7313a3571f327a284d8ac63d6a56437a72ed0e0"}, + {file = "pyproj-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:8fbac2eb9a0e425d7d6b7c6f4ebacd675cf3bdef0c59887057b8b4b0374e7c12"}, + {file = "pyproj-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:95120d65cbc5983dfd877076f28dbc18b9b329cbee38ca6e217bb7a5a043c099"}, + {file = "pyproj-3.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:830e6de7cfe43853967afee5ef908dfd5aa72d1ec12af9b9e3fecc179886e346"}, + {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e342b3010b2b20134671564ff9a8c476e5e512bf589477480aded1a5813af7c8"}, + {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23787460fab85ba2f857ee60ffb2e8e21fd9bd5db9833c51c1c05b2a6d9f0be5"}, + {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595376e4d3bb72b7dceeccbce0f4c43053d47561f17a1ad0224407e9980ee849"}, + {file = "pyproj-3.6.0-cp39-cp39-win32.whl", hash = "sha256:4d8a9773503085eada59b6892c96ddf686ab8cf64cfdc18ad744d13ee76dfa6f"}, + {file = "pyproj-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:137a07404f937f264b11b7130cd4cfa00002dbe4333b222e8056db84849c2ea4"}, + {file = "pyproj-3.6.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2799499a4045e4fb73e44c31bdacab0593a253a7a4b6baae6fdd27d604cf9bc2"}, + {file = "pyproj-3.6.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f04f6297c615c3b17f835df2556ac8fb9b4f51f281e960437eaf0cd80e7ae26a"}, + {file = "pyproj-3.6.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a4d2d438b007cb1f8d5f6f308d53d7ff9a2508cff8f9da6e2a93b76ffd98aaf"}, + {file = "pyproj-3.6.0.tar.gz", hash = "sha256:a5b111865b3f0f8b77b3983f2fbe4dd6248fc09d3730295949977c8dcd988062"}, +] [package.dependencies] certifi = "*" [[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" +name = "pyquery" +version = "2.0.0" +description = "A jquery-like library for python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = "*" +files = [ + {file = "pyquery-2.0.0-py3-none-any.whl", hash = "sha256:8dfc9b4b7c5f877d619bbae74b1898d5743f6ca248cfd5d72b504dd614da312f"}, + {file = "pyquery-2.0.0.tar.gz", hash = "sha256:963e8d4e90262ff6d8dec072ea97285dc374a2f69cad7776f4082abcf6a1d8ae"}, +] + +[package.dependencies] +cssselect = ">=1.2.0" +lxml = ">=2.1" + +[package.extras] +test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] [[package]] name = "pystac" -version = "1.7.3" -description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." +version = "1.8.3" +description = "Python library for working with the SpatioTemporal Asset Catalog (STAC) specification" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "pystac-1.8.3-py3-none-any.whl", hash = "sha256:91805520b0b5386db84aae5296dc6d4fb6754410c481d0a00a8afedc3b4c75d5"}, + {file = "pystac-1.8.3.tar.gz", hash = "sha256:3fd0464bfeb7e99893b24c8d683dd3d046c48b2e53ed65d0a8a704f1281f1ed1"}, +] [package.dependencies] python-dateutil = ">=2.7.0" [package.extras] +bench = ["asv (>=0.5,<1.0)", "virtualenv (>=20.22,<21.0)"] +docs = ["Sphinx (>=6.2,<7.0)", "ipython (>=8.12,<9.0)", "jinja2 (<4.0)", "jupyter (>=1.0,<2.0)", "nbsphinx (>=0.9,<1.0)", "pydata-sphinx-theme (>=0.13,<1.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-design (>=0.4,<1.0)", "sphinxcontrib-fulltoc (>=1.2,<2.0)"] +jinja2 = ["jinja2 (<4.0)"] orjson = ["orjson (>=3.5)"] +test = ["black (>=23.3,<24.0)", "codespell (>=2.2,<3.0)", "coverage (>=7.2,<8.0)", "doc8 (>=1.1,<2.0)", "html5lib (>=1.1,<2.0)", "jinja2 (<4.0)", "jsonschema (>=4.0.1,<4.18)", "mypy (>=1.2,<2.0)", "orjson (>=3.8,<4.0)", "pre-commit (>=3.2,<4.0)", "pytest (>=7.3,<8.0)", "pytest-cov (>=4.0,<5.0)", "pytest-mock (>=3.10,<4.0)", "pytest-recording (>=0.13,<1.0)", "ruff (==0.0.284)", "types-html5lib (>=1.1,<2.0)", "types-orjson (>=3.6,<4.0)", "types-python-dateutil (>=2.8,<3.0)", "types-urllib3 (>=1.26,<2.0)"] urllib3 = ["urllib3 (>=1.26)"] -validation = ["jsonschema (>=4.0.1)"] +validation = ["jsonschema (>=4.0.1,<4.18)"] [[package]] name = "pystac-client" @@ -2210,6 +4170,10 @@ description = "Python library for working with Spatiotemporal Asset Catalog (STA category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "pystac-client-0.6.1.tar.gz", hash = "sha256:1981537ad0fd167b08790eb3f41e7c2788438f461125b42b47bc934eaf1adcb1"}, + {file = "pystac_client-0.6.1-py3-none-any.whl", hash = "sha256:124d81bd9653b3e12c7ff244bf0dad420cadeaf86ab394dfdc804958ff723fcd"}, +] [package.dependencies] pystac = ">=1.7.0" @@ -2221,11 +4185,15 @@ validation = ["jsonschema (>=4.5.1)"] [[package]] name = "pytest" -version = "7.3.1" +version = "7.4.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, +] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -2236,15 +4204,19 @@ 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", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" -version = "4.0.0" +version = "4.1.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} @@ -2260,6 +4232,10 @@ description = "pytest plugin for printing summary data as I want it" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest_pretty-1.2.0-py3-none-any.whl", hash = "sha256:6f79122bf53864ae2951b6c9e94d7a06a87ef753476acd4588aeac018f062036"}, + {file = "pytest_pretty-1.2.0.tar.gz", hash = "sha256:105a355f128e392860ad2c478ae173ff96d2f03044692f9818ff3d49205d3a60"}, +] [package.dependencies] pytest = ">=7" @@ -2267,11 +4243,15 @@ rich = ">=12" [[package]] name = "pytest-xdist" -version = "3.2.1" +version = "3.3.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-xdist-3.3.1.tar.gz", hash = "sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93"}, + {file = "pytest_xdist-3.3.1-py3-none-any.whl", hash = "sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"}, +] [package.dependencies] execnet = ">=1.1" @@ -2289,21 +4269,14 @@ description = "Extensions to the standard Python datetime module" category = "dev" 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 = "python-dotenv" -version = "1.0.0" -description = "Read key-value pairs from a .env file and set them as environment variables" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.extras] -cli = ["click (>=5.0)"] - [[package]] name = "pytkdocs" version = "0.16.1" @@ -2311,9 +4284,10 @@ description = "Load Python objects documentation." category = "dev" optional = false python-versions = ">=3.7" - -[package.dependencies] -astunparse = {version = ">=1.6", markers = "python_version < \"3.9\""} +files = [ + {file = "pytkdocs-0.16.1-py3-none-any.whl", hash = "sha256:a8c3f46ecef0b92864cc598e9101e9c4cf832ebbf228f50c84aa5dd850aac379"}, + {file = "pytkdocs-0.16.1.tar.gz", hash = "sha256:e2ccf6dfe9dbbceb09818673f040f1a7c32ed0bffb2d709b06be6453c4026045"}, +] [package.extras] numpy-style = ["docstring_parser (>=0.7)"] @@ -2325,6 +4299,10 @@ description = "World timezone definitions, modern and historical" category = "dev" optional = false python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] [[package]] name = "pywin32" @@ -2333,14 +4311,72 @@ description = "Python for Window Extensions" category = "dev" optional = false python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" category = "main" 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-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-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {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-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-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 = "pyyaml-env-tag" @@ -2349,28 +4385,146 @@ description = "A custom YAML tag for referencing environment variables in YAML f category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] [package.dependencies] pyyaml = "*" [[package]] name = "pyzmq" -version = "25.0.2" +version = "25.1.1" description = "Python bindings for 0MQ" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76"}, + {file = "pyzmq-25.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849"}, + {file = "pyzmq-25.1.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7"}, + {file = "pyzmq-25.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9"}, + {file = "pyzmq-25.1.1-cp310-cp310-win32.whl", hash = "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790"}, + {file = "pyzmq-25.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f"}, + {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83"}, + {file = "pyzmq-25.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9"}, + {file = "pyzmq-25.1.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752"}, + {file = "pyzmq-25.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca"}, + {file = "pyzmq-25.1.1-cp311-cp311-win32.whl", hash = "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329"}, + {file = "pyzmq-25.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6"}, + {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762"}, + {file = "pyzmq-25.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a"}, + {file = "pyzmq-25.1.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e"}, + {file = "pyzmq-25.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb"}, + {file = "pyzmq-25.1.1-cp312-cp312-win32.whl", hash = "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075"}, + {file = "pyzmq-25.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787"}, + {file = "pyzmq-25.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062"}, + {file = "pyzmq-25.1.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e"}, + {file = "pyzmq-25.1.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123"}, + {file = "pyzmq-25.1.1-cp36-cp36m-win32.whl", hash = "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71"}, + {file = "pyzmq-25.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3"}, + {file = "pyzmq-25.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0"}, + {file = "pyzmq-25.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7"}, + {file = "pyzmq-25.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae"}, + {file = "pyzmq-25.1.1-cp37-cp37m-win32.whl", hash = "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e"}, + {file = "pyzmq-25.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3"}, + {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a"}, + {file = "pyzmq-25.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f"}, + {file = "pyzmq-25.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2"}, + {file = "pyzmq-25.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0"}, + {file = "pyzmq-25.1.1-cp38-cp38-win32.whl", hash = "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c"}, + {file = "pyzmq-25.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1"}, + {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45"}, + {file = "pyzmq-25.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae"}, + {file = "pyzmq-25.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8"}, + {file = "pyzmq-25.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2"}, + {file = "pyzmq-25.1.1-cp39-cp39-win32.whl", hash = "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2"}, + {file = "pyzmq-25.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996"}, + {file = "pyzmq-25.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a"}, + {file = "pyzmq-25.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728"}, + {file = "pyzmq-25.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180"}, + {file = "pyzmq-25.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304"}, + {file = "pyzmq-25.1.1.tar.gz", hash = "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23"}, +] [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "rasterio" -version = "1.3.6" +version = "1.3.8" description = "Fast and direct raster I/O for use with Numpy and SciPy" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "rasterio-1.3.8-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:fea5db183fd1c85e7f41651af5b474af09a68a5e12ce37cad8cc7708843f1ea4"}, + {file = "rasterio-1.3.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e2207003854af60a879cdd87da033cbf86a53585dbf2a49045f66decc3bbb01"}, + {file = "rasterio-1.3.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ec3bfc55c793d1dc7437f3d8b55116db5ea1cf4e0c25c96999fd99daf1ae6f"}, + {file = "rasterio-1.3.8-cp310-cp310-win_amd64.whl", hash = "sha256:ce5c3193b141d23fe081e6b97665f072af48556622da6ae4d45d3a2192e38c3f"}, + {file = "rasterio-1.3.8-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d5ccc8e6d30534d510ce5099d4a35616611cadcae79aa1216150c2696e03ddde"}, + {file = "rasterio-1.3.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3b8410be847e8fd96cbe744e28e484437b370830052b5dcc7b11efc8c73fffc"}, + {file = "rasterio-1.3.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8e1b456f58b9ae023026730320424091af504ef066418ddcd296b9014845ee"}, + {file = "rasterio-1.3.8-cp311-cp311-win_amd64.whl", hash = "sha256:0323332ed1bfad522e53a3da45e0d3453e603862c3d2c08d8a639a7be76853fb"}, + {file = "rasterio-1.3.8-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d177157a9a033a0642b3102d9f9e169bada56f1e25c982d2549359a3f397dcff"}, + {file = "rasterio-1.3.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:969b943d3746bad7cc9e2433deb4d21a6f0b21a5b46daeb95530b79fe010910b"}, + {file = "rasterio-1.3.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eefa29a8d5dfd6537fee6e7f28be7b78ceedb85026851c58759563ef7541dc0c"}, + {file = "rasterio-1.3.8-cp38-cp38-win_amd64.whl", hash = "sha256:d184ad8d29c9c8a04d265cdc229d446c59b142d36228926a17767c1758469c8a"}, + {file = "rasterio-1.3.8-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4c9451f51e175940223ad2d3b205a303a810f5d396fbaf0f17fbde6ee1b74737"}, + {file = "rasterio-1.3.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f57d73b5713d8096ec2fc9bb929bf3ce995f3f34d95e32f30192d180921d341a"}, + {file = "rasterio-1.3.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6c466b2b7a49f8ab3ee0ad0974185b806b7c19427dbf3e1cf4372ce0d52b2ee"}, + {file = "rasterio-1.3.8-cp39-cp39-win_amd64.whl", hash = "sha256:3b654e9fd64ad1f68699376a25bd1b403f8b023a75af42e3b26effda990428df"}, + {file = "rasterio-1.3.8.tar.gz", hash = "sha256:ffdd18e78efdf8ad5861065fd812a66dd34264293317ff6540a078ea891cdef8"}, +] [package.dependencies] affine = "*" @@ -2391,21 +4545,147 @@ plot = ["matplotlib"] s3 = ["boto3 (>=1.2.4)"] test = ["boto3 (>=1.2.4)", "hypothesis", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely"] +[[package]] +name = "readtime" +version = "3.0.0" +description = "Calculates the time some text takes the average human to read, based on Medium's read time forumula" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "readtime-3.0.0.tar.gz", hash = "sha256:76c5a0d773ad49858c53b42ba3a942f62fbe20cc8c6f07875797ac7dc30963a9"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.0.1" +markdown2 = ">=2.4.3" +pyquery = ">=1.2" + +[[package]] +name = "referencing" +version = "0.30.2" +description = "JSON Referencing + Python" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, + {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "regex" -version = "2023.5.5" +version = "2023.8.8" description = "Alternative regular expression module, to replace re." category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, + {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, + {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, + {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, + {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, + {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, + {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, + {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, + {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, + {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, + {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, + {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, + {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, + {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, + {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, + {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, + {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, + {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, + {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, + {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, + {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, + {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, + {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, +] [[package]] name = "requests" -version = "2.30.0" +version = "2.31.0" description = "Python HTTP for Humans." category = "dev" 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" @@ -2419,16 +4699,19 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.3.5" +version = "13.5.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false python-versions = ">=3.7.0" +files = [ + {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, + {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, +] [package.dependencies] -markdown-it-py = ">=2.2.0,<3.0.0" +markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] @@ -2440,6 +4723,10 @@ description = "geospatial xarray extension powered by rasterio" category = "dev" optional = false python-versions = ">=3.8" +files = [ + {file = "rioxarray-0.13.4-py3-none-any.whl", hash = "sha256:56eef711d9817d3c729c1a267c940e7dff66bfc874a0b24ed3604ea2f958dfb2"}, + {file = "rioxarray-0.13.4.tar.gz", hash = "sha256:0cad24ad2c3c5ee181a0cfad2b8c2152a609b7eb118a3430034aec171e9cf14f"}, +] [package.dependencies] numpy = ">=1.21" @@ -2456,47 +4743,223 @@ interp = ["scipy"] test = ["dask", "netcdf4", "pytest (>=3.6)", "pytest-cov", "pytest-timeout"] [[package]] -name = "ruff" -version = "0.0.259" -description = "An extremely fast Python linter, written in Rust." +name = "rpds-py" +version = "0.9.2" +description = "Python bindings to Rust's persistent data structures (rpds)" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, + {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"}, + {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"}, + {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"}, + {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"}, + {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"}, + {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"}, + {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"}, + {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"}, + {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"}, + {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"}, + {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"}, + {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"}, + {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"}, + {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"}, + {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"}, + {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"}, + {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"}, + {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"}, + {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"}, + {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"}, + {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"}, + {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"}, + {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"}, + {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"}, + {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"}, + {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"}, + {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"}, + {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"}, + {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"}, + {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, + {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, +] [[package]] -name = "scikit-learn" -version = "1.2.2" -description = "A set of python modules for machine learning and data mining" +name = "ruff" +version = "0.0.259" +description = "An extremely fast Python linter, written in Rust." category = "dev" optional = false -python-versions = ">=3.8" - -[package.dependencies] -joblib = ">=1.1.1" -numpy = ">=1.17.3" -scipy = ">=1.3.2" -threadpoolctl = ">=2.0.0" - -[package.extras] -benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] -tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.259-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f3938dc45e2a3f818e9cbd53007265c22246fbfded8837b2c563bf0ebde1a226"}, + {file = "ruff-0.0.259-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:22e1e35bf5f12072cd644d22afd9203641ccf258bc14ff91aa1c43dc14f6047d"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2fb20e89e85d147c85caa807707a1488bccc1f3854dc3d53533e89b52a0c5ff"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:49e903bcda19f6bb0725a962c058eb5d61f40d84ef52ed53b61939b69402ab4e"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71f0ef1985e9a6696fa97da8459917fa34bdaa2c16bd33bd5edead585b7d44f7"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7cfef26619cba184d59aa7fa17b48af5891d51fc0b755a9bc533478a10d4d066"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79b02fa17ec1fd8d306ae302cb47fb614b71e1f539997858243769bcbe78c6d9"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:428507fb321b386dda70d66cd1a8aa0abf51d7c197983d83bb9e4fa5ee60300b"}, + {file = "ruff-0.0.259-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fbaea9167f1852757f02133e5daacdb8c75b3431343205395da5b10499927a"}, + {file = "ruff-0.0.259-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:40ae87f2638484b7e8a7567b04a7af719f1c484c5bf132038b702bb32e1f6577"}, + {file = "ruff-0.0.259-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:29e2b77b7d5da6a7dd5cf9b738b511355c5734ece56f78e500d4b5bffd58c1a0"}, + {file = "ruff-0.0.259-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b3c1beacf6037e7f0781d4699d9a2dd4ba2462f475be5b1f45cf84c4ba3c69d"}, + {file = "ruff-0.0.259-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:daaea322e7e85f4c13d82be9536309e1c4b8b9851bb0cbc7eeb15d490fd46bf9"}, + {file = "ruff-0.0.259-py3-none-win32.whl", hash = "sha256:38704f151323aa5858370a2f792e122cc25e5d1aabe7d42ceeab83da18f0b456"}, + {file = "ruff-0.0.259-py3-none-win_amd64.whl", hash = "sha256:aa9449b898287e621942cc71b9327eceb8f0c357e4065fecefb707ef2d978df8"}, + {file = "ruff-0.0.259-py3-none-win_arm64.whl", hash = "sha256:e4f39e18702de69faaaee3969934b92d7467285627f99a5b6ecd55a7d9f5d086"}, + {file = "ruff-0.0.259.tar.gz", hash = "sha256:8b56496063ab3bfdf72339a5fbebb8bd46e5c5fee25ef11a9f03b208fa0562ec"}, +] + +[[package]] +name = "scikit-learn" +version = "1.3.0" +description = "A set of python modules for machine learning and data mining" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "scikit-learn-1.3.0.tar.gz", hash = "sha256:8be549886f5eda46436b6e555b0e4873b4f10aa21c07df45c4bc1735afbccd7a"}, + {file = "scikit_learn-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981287869e576d42c682cf7ca96af0c6ac544ed9316328fd0d9292795c742cf5"}, + {file = "scikit_learn-1.3.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:436aaaae2c916ad16631142488e4c82f4296af2404f480e031d866863425d2a2"}, + {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e28d8fa47a0b30ae1bd7a079519dd852764e31708a7804da6cb6f8b36e3630"}, + {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111"}, + {file = "scikit_learn-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:552fd1b6ee22900cf1780d7386a554bb96949e9a359999177cf30211e6b20df6"}, + {file = "scikit_learn-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79970a6d759eb00a62266a31e2637d07d2d28446fca8079cf9afa7c07b0427f8"}, + {file = "scikit_learn-1.3.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:850a00b559e636b23901aabbe79b73dc604b4e4248ba9e2d6e72f95063765603"}, + {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee04835fb016e8062ee9fe9074aef9b82e430504e420bff51e3e5fffe72750ca"}, + {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d953531f5d9f00c90c34fa3b7d7cfb43ecff4c605dac9e4255a20b114a27369"}, + {file = "scikit_learn-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:151ac2bf65ccf363664a689b8beafc9e6aae36263db114b4ca06fbbbf827444a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a885a9edc9c0a341cab27ec4f8a6c58b35f3d449c9d2503a6fd23e06bbd4f6a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9877af9c6d1b15486e18a94101b742e9d0d2f343d35a634e337411ddb57783f3"}, + {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c470f53cea065ff3d588050955c492793bb50c19a92923490d18fcb637f6383a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6e2d7389542eae01077a1ee0318c4fec20c66c957f45c7aac0c6eb0fe3c612"}, + {file = "scikit_learn-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:3a11936adbc379a6061ea32fa03338d4ca7248d86dd507c81e13af428a5bc1db"}, + {file = "scikit_learn-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:998d38fcec96584deee1e79cd127469b3ad6fefd1ea6c2dfc54e8db367eb396b"}, + {file = "scikit_learn-1.3.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ded35e810438a527e17623ac6deae3b360134345b7c598175ab7741720d7ffa7"}, + {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8102d5036e28d08ab47166b48c8d5e5810704daecf3a476a4282d562be9a28"}, + {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7617164951c422747e7c32be4afa15d75ad8044f42e7d70d3e2e0429a50e6718"}, + {file = "scikit_learn-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d54fb9e6038284548072df22fd34777e434153f7ffac72c8596f2d6987110dd"}, +] + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.5.0" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"] [[package]] name = "scipy" -version = "1.10.1" +version = "1.11.2" description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false -python-versions = "<3.12,>=3.8" +python-versions = "<3.13,>=3.9" +files = [ + {file = "scipy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2b997a5369e2d30c97995dcb29d638701f8000d04df01b8e947f206e5d0ac788"}, + {file = "scipy-1.11.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:95763fbda1206bec41157582bea482f50eb3702c85fffcf6d24394b071c0e87a"}, + {file = "scipy-1.11.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e367904a0fec76433bf3fbf3e85bf60dae8e9e585ffd21898ab1085a29a04d16"}, + {file = "scipy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d690e1ca993c8f7ede6d22e5637541217fc6a4d3f78b3672a6fe454dbb7eb9a7"}, + {file = "scipy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d2b813bfbe8dec6a75164523de650bad41f4405d35b0fa24c2c28ae07fcefb20"}, + {file = "scipy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:afdb0d983f6135d50770dd979df50bf1c7f58b5b33e0eb8cf5c73c70600eae1d"}, + {file = "scipy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d9886f44ef8c9e776cb7527fb01455bf4f4a46c455c4682edc2c2cc8cd78562"}, + {file = "scipy-1.11.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1342ca385c673208f32472830c10110a9dcd053cf0c4b7d4cd7026d0335a6c1d"}, + {file = "scipy-1.11.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b133f237bd8ba73bad51bc12eb4f2d84cbec999753bf25ba58235e9fc2096d80"}, + {file = "scipy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aeb87661de987f8ec56fa6950863994cd427209158255a389fc5aea51fa7055"}, + {file = "scipy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:90d3b1364e751d8214e325c371f0ee0dd38419268bf4888b2ae1040a6b266b2a"}, + {file = "scipy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:f73102f769ee06041a3aa26b5841359b1a93cc364ce45609657751795e8f4a4a"}, + {file = "scipy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa4909c6c20c3d91480533cddbc0e7c6d849e7d9ded692918c76ce5964997898"}, + {file = "scipy-1.11.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ac74b1512d38718fb6a491c439aa7b3605b96b1ed3be6599c17d49d6c60fca18"}, + {file = "scipy-1.11.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8425fa963a32936c9773ee3ce44a765d8ff67eed5f4ac81dc1e4a819a238ee9"}, + {file = "scipy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:542a757e2a6ec409e71df3d8fd20127afbbacb1c07990cb23c5870c13953d899"}, + {file = "scipy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea932570b1c2a30edafca922345854ff2cd20d43cd9123b6dacfdecebfc1a80b"}, + {file = "scipy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:4447ad057d7597476f9862ecbd9285bbf13ba9d73ce25acfa4e4b11c6801b4c9"}, + {file = "scipy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b0620240ef445b5ddde52460e6bc3483b7c9c750275369379e5f609a1050911c"}, + {file = "scipy-1.11.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:f28f1f6cfeb48339c192efc6275749b2a25a7e49c4d8369a28b6591da02fbc9a"}, + {file = "scipy-1.11.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:214cdf04bbae7a54784f8431f976704ed607c4bc69ba0d5d5d6a9df84374df76"}, + {file = "scipy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10eb6af2f751aa3424762948e5352f707b0dece77288206f227864ddf675aca0"}, + {file = "scipy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0f3261f14b767b316d7137c66cc4f33a80ea05841b9c87ad83a726205b901423"}, + {file = "scipy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:2c91cf049ffb5575917f2a01da1da082fd24ed48120d08a6e7297dfcac771dcd"}, + {file = "scipy-1.11.2.tar.gz", hash = "sha256:b29318a5e39bd200ca4381d80b065cdf3076c7d7281c5e36569e99273867f61d"}, +] [package.dependencies] -numpy = ">=1.19.5,<1.27.0" +numpy = ">=1.21.6,<1.28.0" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +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]] @@ -2506,6 +4969,10 @@ description = "Statistical data visualization" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "seaborn-0.12.2-py3-none-any.whl", hash = "sha256:ebf15355a4dba46037dfd65b7350f014ceb1f13c05e814eda2c9f5fd731afc08"}, + {file = "seaborn-0.12.2.tar.gz", hash = "sha256:374645f36509d0dcab895cba5b47daf0586f77bfe3b36c97c607db7da5be0139"}, +] [package.dependencies] matplotlib = ">=3.1,<3.6.1 || >3.6.1" @@ -2519,35 +4986,21 @@ stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] [[package]] name = "setuptools" -version = "67.7.2" +version = "68.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"}, + {file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"}, +] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "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 (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "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]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] -[[package]] -name = "setuptools-scm" -version = "7.1.0" -description = "the blessed package to manage your versions by scm tags" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -packaging = ">=20.0" -setuptools = "*" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} -typing-extensions = "*" - -[package.extras] -test = ["pytest (>=6.2)", "virtualenv (>20)"] -toml = ["setuptools (>=42)"] - [[package]] name = "shapely" version = "2.0.1" @@ -2555,6 +5008,46 @@ description = "Manipulation and analysis of geometric objects" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b06d031bc64149e340448fea25eee01360a58936c89985cf584134171e05863f"}, + {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a6ac34c16f4d5d3c174c76c9d7614ec8fe735f8f82b6cc97a46b54f386a86bf"}, + {file = "shapely-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:865bc3d7cc0ea63189d11a0b1120d1307ed7a64720a8bfa5be2fde5fc6d0d33f"}, + {file = "shapely-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45b4833235b90bc87ee26c6537438fa77559d994d2d3be5190dd2e54d31b2820"}, + {file = "shapely-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce88ec79df55430e37178a191ad8df45cae90b0f6972d46d867bf6ebbb58cc4d"}, + {file = "shapely-2.0.1-cp310-cp310-win32.whl", hash = "sha256:01224899ff692a62929ef1a3f5fe389043e262698a708ab7569f43a99a48ae82"}, + {file = "shapely-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:da71de5bf552d83dcc21b78cc0020e86f8d0feea43e202110973987ffa781c21"}, + {file = "shapely-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:502e0a607f1dcc6dee0125aeee886379be5242c854500ea5fd2e7ac076b9ce6d"}, + {file = "shapely-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7d3bbeefd8a6a1a1017265d2d36f8ff2d79d0162d8c141aa0d37a87063525656"}, + {file = "shapely-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f470a130d6ddb05b810fc1776d918659407f8d025b7f56d2742a596b6dffa6c7"}, + {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4641325e065fd3e07d55677849c9ddfd0cf3ee98f96475126942e746d55b17c8"}, + {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90cfa4144ff189a3c3de62e2f3669283c98fb760cfa2e82ff70df40f11cadb39"}, + {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70a18fc7d6418e5aea76ac55dce33f98e75bd413c6eb39cfed6a1ba36469d7d4"}, + {file = "shapely-2.0.1-cp311-cp311-win32.whl", hash = "sha256:09d6c7763b1bee0d0a2b84bb32a4c25c6359ad1ac582a62d8b211e89de986154"}, + {file = "shapely-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:d8f55f355be7821dade839df785a49dc9f16d1af363134d07eb11e9207e0b189"}, + {file = "shapely-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:83a8ec0ee0192b6e3feee9f6a499d1377e9c295af74d7f81ecba5a42a6b195b7"}, + {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a529218e72a3dbdc83676198e610485fdfa31178f4be5b519a8ae12ea688db14"}, + {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91575d97fd67391b85686573d758896ed2fc7476321c9d2e2b0c398b628b961c"}, + {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8b0d834b11be97d5ab2b4dceada20ae8e07bcccbc0f55d71df6729965f406ad"}, + {file = "shapely-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:b4f0711cc83734c6fad94fc8d4ec30f3d52c1787b17d9dca261dc841d4731c64"}, + {file = "shapely-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:05c51a29336e604c084fb43ae5dbbfa2c0ef9bd6fedeae0a0d02c7b57a56ba46"}, + {file = "shapely-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b519cf3726ddb6c67f6a951d1bb1d29691111eaa67ea19ddca4d454fbe35949c"}, + {file = "shapely-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:193a398d81c97a62fc3634a1a33798a58fd1dcf4aead254d080b273efbb7e3ff"}, + {file = "shapely-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e55698e0ed95a70fe9ff9a23c763acfe0bf335b02df12142f74e4543095e9a9b"}, + {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32a748703e7bf6e92dfa3d2936b2fbfe76f8ce5f756e24f49ef72d17d26ad02"}, + {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a34a23d6266ca162499e4a22b79159dc0052f4973d16f16f990baa4d29e58b6"}, + {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173d24e85e51510e658fb108513d5bc11e3fd2820db6b1bd0522266ddd11f51"}, + {file = "shapely-2.0.1-cp38-cp38-win32.whl", hash = "sha256:3cb256ae0c01b17f7bc68ee2ffdd45aebf42af8992484ea55c29a6151abe4386"}, + {file = "shapely-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c7eed1fb3008a8a4a56425334b7eb82651a51f9e9a9c2f72844a2fb394f38a6c"}, + {file = "shapely-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ac1dfc397475d1de485e76de0c3c91cc9d79bd39012a84bb0f5e8a199fc17bef"}, + {file = "shapely-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33403b8896e1d98aaa3a52110d828b18985d740cc9f34f198922018b1e0f8afe"}, + {file = "shapely-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2569a4b91caeef54dd5ae9091ae6f63526d8ca0b376b5bb9fd1a3195d047d7d4"}, + {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a70a614791ff65f5e283feed747e1cc3d9e6c6ba91556e640636bbb0a1e32a71"}, + {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43755d2c46b75a7b74ac6226d2cc9fa2a76c3263c5ae70c195c6fb4e7b08e79"}, + {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad81f292fffbd568ae71828e6c387da7eb5384a79db9b4fde14dd9fdeffca9a"}, + {file = "shapely-2.0.1-cp39-cp39-win32.whl", hash = "sha256:b50c401b64883e61556a90b89948297f1714dbac29243d17ed9284a47e6dd731"}, + {file = "shapely-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bca57b683e3d94d0919e2f31e4d70fdfbb7059650ef1b431d9f4e045690edcd5"}, + {file = "shapely-2.0.1.tar.gz", hash = "sha256:66a6b1a3e72ece97fc85536a281476f9b7794de2e646ca8a4517e2e3c1446893"}, +] [package.dependencies] numpy = ">=1.14" @@ -2570,6 +5063,10 @@ description = "" category = "main" optional = false python-versions = ">=3.8,<3.12" +files = [ + {file = "simple_pytree-0.1.7-py3-none-any.whl", hash = "sha256:d84834955b153eeb22a944bdfeff7ce1a261e31ef347f0b1e07bb0eedbb3f0ea"}, + {file = "simple_pytree-0.1.7.tar.gz", hash = "sha256:037c5c492de191038c6625fb223da572ec321e829150f48c452e100d69bbffba"}, +] [package.dependencies] jax = "*" @@ -2582,6 +5079,10 @@ description = "Python 2 and 3 compatibility utilities" category = "main" 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 = "smmap" @@ -2590,6 +5091,10 @@ description = "A pure Python implementation of a sliding window memory map manag category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] [[package]] name = "snowballstemmer" @@ -2598,6 +5103,10 @@ description = "This package provides 29 stemmers for 28 languages generated from category = "dev" optional = false python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] [[package]] name = "snuggs" @@ -2606,6 +5115,10 @@ description = "Snuggs are s-expressions for Numpy" category = "dev" optional = false python-versions = "*" +files = [ + {file = "snuggs-1.4.7-py3-none-any.whl", hash = "sha256:988dde5d4db88e9d71c99457404773dabcc7a1c45971bfbe81900999942d9f07"}, + {file = "snuggs-1.4.7.tar.gz", hash = "sha256:501cf113fe3892e14e2fee76da5cd0606b7e149c411c271898e6259ebde2617b"}, +] [package.dependencies] numpy = "*" @@ -2621,6 +5134,10 @@ description = "A modern CSS selector implementation for Beautiful Soup." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, + {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, +] [[package]] name = "stack-data" @@ -2629,6 +5146,10 @@ description = "Extract data from python stack frames and tracebacks for informat category = "dev" optional = false python-versions = "*" +files = [ + {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, + {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, +] [package.dependencies] asttokens = ">=2.1.0" @@ -2645,6 +5166,10 @@ description = "Pretty-print tabular data" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] [package.extras] widechars = ["wcwidth"] @@ -2656,6 +5181,9 @@ description = "Probabilistic modeling and statistical inference in TensorFlow" category = "main" optional = false python-versions = "*" +files = [ + {file = "tensorflow_probability-0.19.0-py2.py3-none-any.whl", hash = "sha256:ee70967fbd52b09e9c5ec148a9437c4cf3f9e9d689cdca400a1bc921f21cdcac"}, +] [package.dependencies] absl-py = "*" @@ -2672,22 +5200,45 @@ tfds = ["tensorflow-datasets (>=2.2.0)"] [[package]] name = "tensorstore" -version = "0.1.36" +version = "0.1.41" description = "Read and write large, multi-dimensional arrays" category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "tensorstore-0.1.41-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:bbd58cedddce29216703a63ea42db010b6151c7bc05ac741af50aa31e31491fb"}, + {file = "tensorstore-0.1.41-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91549a16b1ef2d6bc5ac8f28eed32737001fcfe33309f1ba126cd4c1e08b971b"}, + {file = "tensorstore-0.1.41-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:803fa2bcbc93f43fe0b3b5b70d78882d3b266a70d419acfc7fdd515f89cba79b"}, + {file = "tensorstore-0.1.41-cp310-cp310-win_amd64.whl", hash = "sha256:74e317ef7cba8c0208c5d8d9f1406eac37f58e8f92b3f7caa9a72b8b118b1c09"}, + {file = "tensorstore-0.1.41-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:025a62bb9122364885e90469af05fec2f62ad05f46ff46d9eae1d76ad9125563"}, + {file = "tensorstore-0.1.41-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:620ad460023eeeae721e2e25a2a3e2b608f09cd169c1f68af7043c6d44e88cbf"}, + {file = "tensorstore-0.1.41-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96fb62a880bf25da7e12ad4bba00a82deb2daf6f59050e8db6f0b04107120799"}, + {file = "tensorstore-0.1.41-cp311-cp311-win_amd64.whl", hash = "sha256:8b5dbc0e809c90377527e0f65829d6abcdf5c69f892f433ed2cb8508d4ba519a"}, + {file = "tensorstore-0.1.41-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:2aa81581f768382a38584698a3fcb07a533fc391067467326656f24ab019cba1"}, + {file = "tensorstore-0.1.41-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c4c578e82866b8f764de871ff7e0a81fe0949ac3565d8d2eb10f29e43020a52"}, + {file = "tensorstore-0.1.41-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:634c78fd62cd6e5357291ccb9671e43262f818f9cf7cc58f701b5bd80d1c1ef7"}, + {file = "tensorstore-0.1.41-cp38-cp38-win_amd64.whl", hash = "sha256:6b3b14616f9141b12e61c0c46d1c954927f7f307498d8b9d2261ff2bd4005bbd"}, + {file = "tensorstore-0.1.41-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:8df13f990acc58889160eff5b2e1df029cdfffdf020ce5044e655242c1016bb1"}, + {file = "tensorstore-0.1.41-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c400aa46fc814edd69c72fcdf202dbd8c666ae684b534e81350a3a30ab16bdfc"}, + {file = "tensorstore-0.1.41-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a99b87b65dfca65a830503bdfd2e5168a69b5290807cb8e922fa5a1acea2edec"}, + {file = "tensorstore-0.1.41-cp39-cp39-win_amd64.whl", hash = "sha256:2d65ea0fd5ac96a9d577f16bb917ae8a0a121d2093472bfb7bd762b1e32c753b"}, + {file = "tensorstore-0.1.41.tar.gz", hash = "sha256:5168f7f71e51da7d6cc85a11cd5d102d9eae750d5f5a3ee90cc9ebae10226621"}, +] [package.dependencies] numpy = ">=1.16.0" [[package]] name = "threadpoolctl" -version = "3.1.0" +version = "3.2.0" description = "threadpoolctl" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +files = [ + {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"}, + {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"}, +] [[package]] name = "tinycss2" @@ -2696,6 +5247,10 @@ description = "A tiny CSS parser" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, + {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, +] [package.dependencies] webencodings = ">=0.4" @@ -2711,6 +5266,10 @@ description = "Python Library for Tom's Obvious, Minimal Language" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] [[package]] name = "tomli" @@ -2719,14 +5278,22 @@ description = "A lil' TOML parser" category = "dev" 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 = "tomlkit" -version = "0.11.8" +version = "0.12.1" description = "Style preserving TOML library" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, + {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, +] [[package]] name = "toolz" @@ -2735,28 +5302,49 @@ description = "List processing tools and functional utilities" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, + {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, +] [[package]] name = "tornado" -version = "6.3.1" +version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "dev" optional = false python-versions = ">= 3.8" +files = [ + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, + {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, + {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, + {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, +] [[package]] name = "tqdm" -version = "4.65.0" +version = "4.66.1" description = "Fast, Extensible Progress Meter" category = "main" 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 = ["py-make (>=0.1.0)", "twine", "wheel"] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -2768,6 +5356,10 @@ description = "Traitlets Python configuration system" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, + {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, +] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] @@ -2775,27 +5367,34 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typeguard" -version = "3.0.2" +version = "4.1.2" description = "Run-time type checker for Python" category = "main" optional = false python-versions = ">=3.7.4" +files = [ + {file = "typeguard-4.1.2-py3-none-any.whl", hash = "sha256:e00775920d4c91e93a0db0ed473ecda9cfaca578aed3ce0ed3ba7f3cc38eab9c"}, + {file = "typeguard-4.1.2.tar.gz", hash = "sha256:3be187945f9ef5a9f6d7a926dfe54babb7dfd807085ce05f9a5e8735f2487990"}, +] [package.dependencies] -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} -typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.7.0", markers = "python_version < \"3.12\""} [package.extras] -doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["mypy (>=0.991)", "pytest (>=7)"] +doc = ["Sphinx (<7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["mypy (>=1.2.0)", "pytest (>=7)"] [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, +] [[package]] name = "uc-micro-py" @@ -2804,17 +5403,25 @@ description = "Micro subset of unicode data files for linkify-it-py projects." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, + {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, +] [package.extras] test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.0.2" +version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, +] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] @@ -2824,34 +5431,46 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "validators" -version = "0.20.0" -description = "Python Data Validation for Humans™." +version = "0.21.2" +description = "Python Data Validation for Humans™" category = "dev" optional = false -python-versions = ">=3.4" - -[package.dependencies] -decorator = ">=3.4.0" +python-versions = ">=3.8" +files = [ + {file = "validators-0.21.2-py3-none-any.whl", hash = "sha256:6ad95131005a9d4c734a69dd4ef08cf66961e61222e60da25a9b5137cecd6fd4"}, + {file = "validators-0.21.2.tar.gz", hash = "sha256:002ba1552076535176824e43149c18c06f6b611bc8b597ddbcf8770bcf5f9f5c"}, +] [package.extras] -test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] +docs-offline = ["myst-parser (>=2.0.0)", "pypandoc-binary (>=1.11)", "sphinx (>=7.1.1)"] +docs-online = ["mkdocs (>=1.5.2)", "mkdocs-material (>=9.1.21)", "mkdocstrings[python] (>=0.22.0)", "pyaml (>=23.7.0)"] +hooks = ["pre-commit (>=3.3.3)"] +runner = ["tox (>=4.6.4)"] +sast = ["bandit[toml] (>=1.7.5)"] +testing = ["pytest (>=7.4.0)"] +tooling = ["black (>=23.7.0)", "pyright (>=1.1.320)", "ruff (>=0.0.280)"] +tooling-extras = ["pyaml (>=23.7.0)", "pypandoc-binary (>=1.11)", "pytest (>=7.4.0)"] [[package]] name = "virtualenv" -version = "20.23.0" +version = "20.24.3" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.24.3-py3-none-any.whl", hash = "sha256:95a6e9398b4967fbcb5fef2acec5efaf9aa4972049d9ae41f95e0972a683fd02"}, + {file = "virtualenv-20.24.3.tar.gz", hash = "sha256:e5c3b4ce817b0b328af041506a2a299418c98747c4b1e68cb7527e74ced23efc"}, +] [package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.11,<4" -platformdirs = ">=3.2,<4" +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<4" [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "watchdog" @@ -2860,20 +5479,58 @@ description = "Filesystem events monitoring" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, + {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, + {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, + {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, + {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, + {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, + {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, + {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, + {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, +] [package.extras] watchmedo = ["PyYAML (>=3.10)"] [[package]] name = "watermark" -version = "2.3.1" +version = "2.4.3" description = "IPython magic function to print date/time stamps and various system information." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "watermark-2.4.3-py2.py3-none-any.whl", hash = "sha256:39be67f043d7fa0351537fa9b746bbf03ad1bb1ce3d3d84ec96eca954a5e1579"}, + {file = "watermark-2.4.3.tar.gz", hash = "sha256:43d0f7aafb5285af685adce08879f22b2e97be45e786bb93ea4c5e9478dd88e2"}, +] [package.dependencies] -ipython = "*" +importlib-metadata = ">=1.4" +ipython = ">=6.0" +setuptools = "*" + +[package.extras] +gpu = ["py3nvml (>=0.2)"] [[package]] name = "wcwidth" @@ -2882,6 +5539,10 @@ description = "Measures the displayed width of unicode strings in a terminal" category = "dev" optional = false python-versions = "*" +files = [ + {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, + {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, +] [[package]] name = "webencodings" @@ -2890,25 +5551,22 @@ description = "Character encoding aliases for legacy web content" category = "dev" optional = false python-versions = "*" - -[[package]] -name = "wheel" -version = "0.40.0" -description = "A built-package format for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pytest (>=6.0.0)"] +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] [[package]] name = "widgetsnbextension" -version = "4.0.7" +version = "4.0.8" description = "Jupyter interactive widgets for Jupyter Notebook" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "widgetsnbextension-4.0.8-py3-none-any.whl", hash = "sha256:2e37f0ce9da11651056280c7efe96f2db052fe8fc269508e3724f5cbd6c93018"}, + {file = "widgetsnbextension-4.0.8.tar.gz", hash = "sha256:9ec291ba87c2dfad42c3d5b6f68713fa18be1acd7476569516b2431682315c17"}, +] [[package]] name = "wrapt" @@ -2917,2376 +5575,7 @@ description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "xarray" -version = "2023.1.0" -description = "N-D labeled arrays and datasets in Python" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -numpy = ">=1.20" -packaging = ">=21.3" -pandas = ">=1.3" - -[package.extras] -accel = ["bottleneck", "flox", "numbagg", "scipy"] -complete = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "matplotlib", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scipy", "seaborn", "zarr"] -docs = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "ipykernel", "ipython", "jupyter-client", "matplotlib", "nbsphinx", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scanpydoc", "scipy", "seaborn", "sphinx-autosummary-accessors", "sphinx-rtd-theme", "zarr"] -io = ["cfgrib", "cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "rasterio", "scipy", "zarr"] -parallel = ["dask[complete]"] -viz = ["matplotlib", "nc-time-axis", "seaborn"] - -[[package]] -name = "xdoctest" -version = "1.1.1" -description = "A rewrite of the builtin doctest module" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -six = "*" - -[package.extras] -all = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "codecov", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "pytest", "pytest", "pytest", "pytest-cov", "six", "tomli", "typing"] -all-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "codecov (==2.0.15)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "six (==1.11.0)", "tomli (==0.2.0)", "typing (==3.7.4)"] -colors = ["Pygments", "Pygments", "colorama"] -jupyter = ["IPython", "IPython", "attrs", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert"] -optional = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "tomli"] -optional-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "tomli (==0.2.0)"] -runtime-strict = ["six (==1.11.0)"] -tests = ["codecov", "pytest", "pytest", "pytest", "pytest-cov", "typing"] -tests-binary = ["cmake", "cmake", "ninja", "ninja", "pybind11", "pybind11", "scikit-build", "scikit-build"] -tests-binary-strict = ["cmake (==3.21.2)", "cmake (==3.25.0)", "ninja (==1.10.2)", "ninja (==1.11.1)", "pybind11 (==2.10.3)", "pybind11 (==2.7.1)", "scikit-build (==0.11.1)", "scikit-build (==0.16.1)"] -tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "typing (==3.7.4)"] - -[[package]] -name = "yarl" -version = "1.9.2" -description = "Yet another URL library" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" - -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[metadata] -lock-version = "1.1" -python-versions = ">=3.8,<3.12" -content-hash = "38dc9d9bff1be146c749a6fc4706ad71cfe38c51e458fb91076e66cb8d693d29" - -[metadata.files] -absl-py = [ - {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, - {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, -] -absolufy-imports = [ - {file = "absolufy_imports-0.3.1-py2.py3-none-any.whl", hash = "sha256:49bf7c753a9282006d553ba99217f48f947e3eef09e18a700f8a82f75dc7fc5c"}, - {file = "absolufy_imports-0.3.1.tar.gz", hash = "sha256:c90638a6c0b66826d1fb4880ddc20ef7701af34192c94faf40b95d32b59f9793"}, -] -affine = [ - {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, - {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, -] -aiohttp = [ - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"}, - {file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"}, - {file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"}, - {file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"}, - {file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"}, - {file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"}, - {file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"}, - {file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"}, - {file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"}, - {file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"}, - {file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"}, - {file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"}, -] -aiosignal = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, -] -appnope = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] -argcomplete = [ - {file = "argcomplete-2.1.2-py3-none-any.whl", hash = "sha256:4ba9cdaa28c361d251edce884cd50b4b1215d65cdc881bd204426cdde9f52731"}, - {file = "argcomplete-2.1.2.tar.gz", hash = "sha256:fc82ef070c607b1559b5c720529d63b54d9dcf2dcfc2632b10e6372314a34457"}, -] -astroid = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, -] -asttokens = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, -] -astunparse = [ - {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, - {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, -] -asv = [ - {file = "asv-0.6.0.tar.gz", hash = "sha256:9afce3008094209b7e87b7b880bc6b8f2da303fdc6dd665c7be9f1057ecd5753"}, -] -asv-runner = [ - {file = "asv_runner-0.0.9-py3-none-any.whl", hash = "sha256:ef655b451fbe6805b7981ded72d8ac38a8158fa37c770140e1bc6e992e96e5bb"}, - {file = "asv_runner-0.0.9.tar.gz", hash = "sha256:4531cf5677bb19e5bd91d9789378b057037bd17e0d9043621b7ede9eaac88f97"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -attrs = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -beartype = [ - {file = "beartype-0.13.1-py3-none-any.whl", hash = "sha256:c3097b487e57bc278f1b55da8863b704b2a786c46483a6d3df39ab6fe2523d80"}, - {file = "beartype-0.13.1.tar.gz", hash = "sha256:2903947a8a1eb6030264e30108aa72cb1a805cfc9050c0f4014c4aed3a17a00b"}, -] -beautifulsoup4 = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, -] -black = [ - {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, - {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, - {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, - {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, - {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, - {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, - {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, - {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, - {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, - {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, - {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, - {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, - {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, - {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, -] -blackjax = [ - {file = "blackjax-0.9.6-py3-none-any.whl", hash = "sha256:d1c20dd15a63944a7b5c835bac4900aadf8630bedb0d7e51ab7fc63255eb0dd7"}, - {file = "blackjax-0.9.6.tar.gz", hash = "sha256:fb708f183d714750feb475fb87b8162fc1641309f30ee42fd38a5dec82733868"}, -] -bleach = [ - {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, - {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, -] -cached-property = [ - {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, - {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, -] -certifi = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, -] -cffi = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] -cfgv = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, -] -charset-normalizer = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, -] -chex = [ - {file = "chex-0.1.7-py3-none-any.whl", hash = "sha256:9f583015303b1205443843c0b55849bb287f1dfdbd22d9907b1ebb04f964d93e"}, - {file = "chex-0.1.7.tar.gz", hash = "sha256:74ed49799ac4d229881456d468136f1b19a9f9839e3de72b058824e2a4f4dedd"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -click-plugins = [ - {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, - {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, -] -cligj = [ - {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, - {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, -] -cloudpickle = [ - {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, - {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, -] -codespell = [ - {file = "codespell-2.2.4-py3-none-any.whl", hash = "sha256:7d984b8130108e6f82524b7d09f8b7bf2fb1e398c5d4b37d9e2bd310145b3e29"}, - {file = "codespell-2.2.4.tar.gz", hash = "sha256:0b4620473c257d9cde1ff8998b26b2bb209a35c2b7489f5dc3436024298ce83a"}, -] -colorama = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -colorlog = [ - {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, - {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, -] -comm = [ - {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"}, - {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"}, -] -contourpy = [ - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"}, - {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"}, - {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"}, - {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"}, - {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"}, - {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"}, - {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"}, - {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"}, - {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"}, - {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"}, -] -coverage = [ - {file = "coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"}, - {file = "coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"}, - {file = "coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"}, - {file = "coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"}, - {file = "coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"}, - {file = "coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"}, - {file = "coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"}, - {file = "coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"}, - {file = "coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"}, - {file = "coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"}, - {file = "coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"}, - {file = "coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"}, - {file = "coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"}, - {file = "coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"}, - {file = "coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"}, - {file = "coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"}, - {file = "coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"}, - {file = "coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"}, - {file = "coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"}, - {file = "coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"}, - {file = "coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"}, - {file = "coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"}, - {file = "coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"}, - {file = "coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"}, - {file = "coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"}, - {file = "coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"}, - {file = "coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"}, - {file = "coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"}, - {file = "coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"}, - {file = "coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"}, - {file = "coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"}, -] -cycler = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, -] -debugpy = [ - {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"}, - {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"}, - {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"}, - {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"}, - {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"}, - {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"}, - {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"}, - {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"}, - {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"}, - {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"}, - {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"}, - {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"}, - {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"}, - {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"}, - {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"}, - {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"}, - {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"}, - {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"}, -] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -defusedxml = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] -dill = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, -] -distlib = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, -] -dm-tree = [ - {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, - {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, - {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, - {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, - {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, - {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, - {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, - {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, - {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, - {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, - {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, - {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, - {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, - {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, - {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, - {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, -] -etils = [ - {file = "etils-1.2.0-py3-none-any.whl", hash = "sha256:c6585069b387fdbeed6a2c571b8bcf312ecdb577c95065461e5fad9ed1973989"}, - {file = "etils-1.2.0.tar.gz", hash = "sha256:29d369e2dcf43960d9ee338330579d04badd606c88f015f4e1a38d3adbe446d8"}, -] -exceptiongroup = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, -] -execnet = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, -] -executing = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, -] -fastjsonschema = [ - {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, - {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, -] -fastprogress = [ - {file = "fastprogress-1.0.3-py3-none-any.whl", hash = "sha256:6dfea88f7a4717b0a8d6ee2048beae5dbed369f932a368c5dd9caff34796f7c5"}, - {file = "fastprogress-1.0.3.tar.gz", hash = "sha256:7a17d2b438890f838c048eefce32c4ded47197ecc8ea042cecc33d3deb8022f5"}, -] -filelock = [ - {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, - {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, -] -fiona = [ - {file = "Fiona-1.9.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0e9141bdb8031419ed2f04c6da02ae12c3044a81987065e05ff40f39cc35e042"}, - {file = "Fiona-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c0251a57305e6bea3f0a8e8306c0bd05e2b0e30b8a294d7bdc429d5fceca68d"}, - {file = "Fiona-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:894127efde8141bb9383dc4dc890c732f3bfe4d601c3d1020a24fa3c24a8c4a8"}, - {file = "Fiona-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:11ee3d3e6bb5d16f6f1643ffcde7ac4dfa5fbe98a26ce2af05c3c5426ce248d7"}, - {file = "Fiona-1.9.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c99e9bca9e3d6be03a71e9b2f6ba66d446eae9b27df37c1f6b45483b2f215ca0"}, - {file = "Fiona-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a894362c1cf9f33ee931e96cfd4021d3a18f6ccf8c36b87df42a0a494e23545"}, - {file = "Fiona-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0761ff656d07aaef7a7274b74816e16485f0f15e77a962c107cd4a1cfb4757"}, - {file = "Fiona-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:2e61caeabda88ab5fa45db373c2afd6913844b4452c0f2e3e9d924c60bc76fa3"}, - {file = "Fiona-1.9.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:00628c5a3dd7e9bc037ba0487fc3b9f7163107e0a9794bd4c32c471ab65f3a45"}, - {file = "Fiona-1.9.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:95927ddd9afafdb0243bb83bf234557dcdb35bf0e888fd920ff82ffa80f6a53a"}, - {file = "Fiona-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d1064e82a7fed73ce60ce9ce4f65b5a6558fb5b532a13130a17f132ed122ec75"}, - {file = "Fiona-1.9.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:65b096148bfe9a64d87d91ba8e7ff940a5aef8cbffc6738a70e289c6384e1cca"}, - {file = "Fiona-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:38d0d78d4e061592af3441c5962072b0456307246c9c6f412ad38ebef11d2903"}, - {file = "Fiona-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee9b2ec9f0fb4b3798d607a94a5586b403fc27fea06e3e7ac2924c0785d4df61"}, - {file = "Fiona-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:258151f26683a44ed715c09930a42e0b39b3b3444b438ec6e32633f7056740fa"}, - {file = "Fiona-1.9.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:f1fcadad17b00d342532dc51a47128005f8ced01a320fa6b72c8ef669edf3057"}, - {file = "Fiona-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85b6694227ee4e00dfa52c6a9fcc89f1051aaf67df5fbd1faa33fb02c62a6203"}, - {file = "Fiona-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e661deb7a8722839bd27eae74f63f0e480559774cc755598dfa6c51bdf18be3d"}, - {file = "Fiona-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:a57812a584b4a2fb4ffdfaa9135dc38312989f7cd2823ecbd23e11eade5eb7fe"}, - {file = "Fiona-1.9.3.tar.gz", hash = "sha256:60f3789ad9633c3a26acf7cbe39e82e3c7a12562c59af1d599fc3e4e8f7f8f25"}, -] -flax = [ - {file = "flax-0.6.10-py3-none-any.whl", hash = "sha256:8dccc7b84b00ff6f59a36dc0e79f5919498cfeb009a41f8c07f68bf2513198db"}, - {file = "flax-0.6.10.tar.gz", hash = "sha256:e2174a0df7bb4921f29b2cbd33f55ddf6eed161d6df61809fe374a25e473fb2f"}, -] -fonttools = [ - {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"}, - {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"}, -] -frozenlist = [ - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, - {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, - {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, - {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, - {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, - {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, - {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, - {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, - {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, - {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, - {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, -] -fsspec = [ - {file = "fsspec-2023.5.0-py3-none-any.whl", hash = "sha256:51a4ad01a5bb66fcc58036e288c0d53d3975a0df2a5dc59a93b59bade0391f2a"}, - {file = "fsspec-2023.5.0.tar.gz", hash = "sha256:b3b56e00fb93ea321bc9e5d9cf6f8522a0198b20eb24e02774d329e9c6fb84ce"}, -] -gast = [ - {file = "gast-0.5.4-py3-none-any.whl", hash = "sha256:6fc4fa5fa10b72fb8aab4ae58bcb023058386e67b6fa2e3e34cec5c769360316"}, - {file = "gast-0.5.4.tar.gz", hash = "sha256:9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97"}, -] -geopandas = [ - {file = "geopandas-0.12.2-py3-none-any.whl", hash = "sha256:0a470e4bf6f5367e6fd83ab6b40405e0b805c8174665bbcb7c4077ed90202912"}, - {file = "geopandas-0.12.2.tar.gz", hash = "sha256:0acdacddefa176525e4da6d9aeeece225da26055c4becdc6e97cf40fa97c27f4"}, -] -ghp-import = [ - {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, - {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, -] -gitdb = [ - {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, - {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, -] -gitpython = [ - {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, - {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, -] -griffe = [ - {file = "griffe-0.27.4-py3-none-any.whl", hash = "sha256:685350067286229e80a18b8989d6acbd43abdf8b763591221d19c56f4108549e"}, - {file = "griffe-0.27.4.tar.gz", hash = "sha256:088c25fb22f8d1f1add5d3b58a86a3969993181a36ca55b3fa33096a3f3b1a23"}, -] -identify = [ - {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"}, - {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"}, -] -idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] -importlib-metadata = [ - {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, - {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, -] -importlib-resources = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, -] -iniconfig = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] -interrogate = [ - {file = "interrogate-1.5.0-py3-none-any.whl", hash = "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a"}, - {file = "interrogate-1.5.0.tar.gz", hash = "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c"}, -] -ipykernel = [ - {file = "ipykernel-6.23.0-py3-none-any.whl", hash = "sha256:fc886f1dcdc0ec17f277e4d21fd071c857d381adcb04f3f3735d25325ca323c6"}, - {file = "ipykernel-6.23.0.tar.gz", hash = "sha256:bd6f487d9e2744c84f6e667d46462d7647a4c862e70e08282f05a52b9d4b705f"}, -] -ipython = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, -] -ipywidgets = [ - {file = "ipywidgets-8.0.6-py3-none-any.whl", hash = "sha256:a60bf8d2528997e05ac83fd19ea2fbe65f2e79fbe1b2b35779bdfc46c2941dcc"}, - {file = "ipywidgets-8.0.6.tar.gz", hash = "sha256:de7d779f2045d60de9f6c25f653fdae2dba57898e6a1284494b3ba20b6893bb8"}, -] -isort = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] -jax = [ - {file = "jax-0.4.13.tar.gz", hash = "sha256:03bfe6749dfe647f16f15f6616638adae6c4a7ca7167c75c21961ecfd3a3baaa"}, -] -jaxlib = [ - {file = "jaxlib-0.4.13-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:532ebc4fb11386282ad63b83941d4557f4038c1144acf026f1f8565f64c7e9c0"}, - {file = "jaxlib-0.4.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a259bb35429bfbd3b76e43019dfc8f7d6ea94bb217400b78f7d0824ce07a58ac"}, - {file = "jaxlib-0.4.13-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:ea1bc9811ef7d73a15e3213115e88fe7f5d14b59d95027bea9fccc98e5a14af8"}, - {file = "jaxlib-0.4.13-cp310-cp310-win_amd64.whl", hash = "sha256:fde66a93e9be89d99e5792f677ed8e319667d6b2396865b1c52c1312844c47f9"}, - {file = "jaxlib-0.4.13-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:49690fcdd26560515fd15399fc3a44777e0bfc5db5c48fe76ff7bc7228e8b2fb"}, - {file = "jaxlib-0.4.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4e9e34e5d8a6556f62fead14aee0b1614c2c6296f0078d8e6139d6aff109649"}, - {file = "jaxlib-0.4.13-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:8000c0d15c107328e8f7b7b3ac91dd822f5c287a80231882b620503ed141fa89"}, - {file = "jaxlib-0.4.13-cp311-cp311-win_amd64.whl", hash = "sha256:19ae4c316b17a49342432c69f7f89f190b975333f3f9e9e175f686a651bc7347"}, - {file = "jaxlib-0.4.13-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:522635d5e159401a386c79f1236c218c1f68fbb4ca6648115c3ad3c2c3f518ab"}, - {file = "jaxlib-0.4.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:411334d903df07dc1ace8d52fc53c17f6bc1d55aff7f6e0e5cf61ec149f758a0"}, - {file = "jaxlib-0.4.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:839173b2e9593f5e9a6d3c42852cd15070fe80a939246efbb5cf40eec815de89"}, - {file = "jaxlib-0.4.13-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c230ef85712e608d0f048869766a5a63afeb2e72309943db0df9f959ab17307f"}, - {file = "jaxlib-0.4.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d19c05c15f962e098d49b45e2758aacf19330d192ec5395f9ef136f62db90edc"}, - {file = "jaxlib-0.4.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:b5c0a9737efd95fe18fd7715ce30dfce476546705ea8934aad6731777a9631a5"}, - {file = "jaxlib-0.4.13-cp39-cp39-win_amd64.whl", hash = "sha256:bebb4cf001f180dc431f9604daf930c2d9cc778e4dda26f401ac939b7bac912e"}, -] -jaxopt = [ - {file = "jaxopt-0.6-py3-none-any.whl", hash = "sha256:69af71c39969e9e5fa54bd50cbab3e18f6c32659d92e1bf56912a24c8ad0fca6"}, - {file = "jaxopt-0.6.tar.gz", hash = "sha256:19df9cb745ee39fa27f9ba4f01bbec5b0e3a8a1f60320aff553131a5f152c9fa"}, -] -jaxtyping = [ - {file = "jaxtyping-0.2.19-py3-none-any.whl", hash = "sha256:651352032799d422987e783fd1b77699b53c3bb28ffa644bbca5f75ec4fbb843"}, - {file = "jaxtyping-0.2.19.tar.gz", hash = "sha256:21ff4c3caec6781cadfe980b019dde856c1011e17d11dfe8589298040056325a"}, -] -jedi = [ - {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, - {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, -] -jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] -joblib = [ - {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"}, - {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"}, -] -json5 = [ - {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, - {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, -] -jsonschema = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, -] -jupyter-client = [ - {file = "jupyter_client-8.2.0-py3-none-any.whl", hash = "sha256:b18219aa695d39e2ad570533e0d71fb7881d35a873051054a84ee2a17c4b7389"}, - {file = "jupyter_client-8.2.0.tar.gz", hash = "sha256:9fe233834edd0e6c0aa5f05ca2ab4bdea1842bfd2d8a932878212fc5301ddaf0"}, -] -jupyter-core = [ - {file = "jupyter_core-5.3.0-py3-none-any.whl", hash = "sha256:d4201af84559bc8c70cead287e1ab94aeef3c512848dde077b7684b54d67730d"}, - {file = "jupyter_core-5.3.0.tar.gz", hash = "sha256:6db75be0c83edbf1b7c9f91ec266a9a24ef945da630f3120e1a0046dc13713fc"}, -] -jupyterlab-pygments = [ - {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, - {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, -] -jupyterlab-widgets = [ - {file = "jupyterlab_widgets-3.0.7-py3-none-any.whl", hash = "sha256:c73f8370338ec19f1bec47254752d6505b03601cbd5a67e6a0b184532f73a459"}, - {file = "jupyterlab_widgets-3.0.7.tar.gz", hash = "sha256:c3a50ed5bf528a0c7a869096503af54702f86dda1db469aee1c92dc0c01b43ca"}, -] -jupytext = [ - {file = "jupytext-1.14.5-py3-none-any.whl", hash = "sha256:a5dbe60d0ea158bbf82c2bce74aba8d0c220ad7edcda09e017c5eba229b34dc8"}, - {file = "jupytext-1.14.5.tar.gz", hash = "sha256:976e66be8056459a2067e0ec3ff68cc31e00c31895faf9eb893022d319e8f5b4"}, -] -kiwisolver = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, -] -latexcodec = [ - {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, - {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] -linkify-it-py = [ - {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, - {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, -] -markdown = [ - {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, - {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, -] -markdown-it-py = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, -] -markdown-katex = [ - {file = "markdown-katex-202112.1034.tar.gz", hash = "sha256:27892f4cdd6763816f00e4187d0475500697c090aba16630ec4803a6564bf810"}, - {file = "markdown_katex-202112.1034-py2.py3-none-any.whl", hash = "sha256:9ccc5b4b37db7592cc3ea113d763fafe9ffd1b1587e2c217d6145e44a10b4f6d"}, -] -markupsafe = [ - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, - {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, -] -matplotlib = [ - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, - {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, - {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, - {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, - {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, - {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, - {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, - {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, - {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, - {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, -] -matplotlib-inline = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, -] -mccabe = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] -mdit-py-plugins = [ - {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, - {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, -] -mdurl = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] -mdx-truly-sane-lists = [ - {file = "mdx_truly_sane_lists-1.3-py3-none-any.whl", hash = "sha256:b9546a4c40ff8f1ab692f77cee4b6bfe8ddf9cccf23f0a24e71f3716fe290a37"}, - {file = "mdx_truly_sane_lists-1.3.tar.gz", hash = "sha256:b661022df7520a1e113af7c355c62216b384c867e4f59fb8ee7ad511e6e77f45"}, -] -mergedeep = [ - {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, - {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, -] -mistune = [ - {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, - {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, -] -mkdocs = [ - {file = "mkdocs-1.4.3-py3-none-any.whl", hash = "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd"}, - {file = "mkdocs-1.4.3.tar.gz", hash = "sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57"}, -] -mkdocs-autorefs = [ - {file = "mkdocs-autorefs-0.4.1.tar.gz", hash = "sha256:70748a7bd025f9ecd6d6feeba8ba63f8e891a1af55f48e366d6d6e78493aba84"}, - {file = "mkdocs_autorefs-0.4.1-py3-none-any.whl", hash = "sha256:a2248a9501b29dc0cc8ba4c09f4f47ff121945f6ce33d760f145d6f89d313f5b"}, -] -mkdocs-bibtex = [ - {file = "mkdocs-bibtex-2.8.16.tar.gz", hash = "sha256:d4f4d284a72a7a943ab427fff58e74409fb26eb0536f89f202c891fdda2eb50a"}, -] -mkdocs-gen-files = [ - {file = "mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea"}, - {file = "mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc"}, -] -mkdocs-git-authors-plugin = [ - {file = "mkdocs-git-authors-plugin-0.7.0.tar.gz", hash = "sha256:087b63090ebbf6b93f20d8b8e5fbac8e8b140e2107e432ca2ac8dd1d3a1000f5"}, - {file = "mkdocs_git_authors_plugin-0.7.0-py3-none-any.whl", hash = "sha256:cc469208f98e9db08561eac08a9d8ccd0209a60ee5bd0e3e94b6840a5abc54b6"}, -] -mkdocs-jupyter = [ - {file = "mkdocs_jupyter-0.24.1-py3-none-any.whl", hash = "sha256:759833c7d1528ae2d6337342786be7bc1e2235b0b98e9326427d4cf8d4eebee0"}, - {file = "mkdocs_jupyter-0.24.1.tar.gz", hash = "sha256:9677037fb7e931268f3df7599fc0828c261247df3d1575bced320ba8b7d1d46d"}, -] -mkdocs-literate-nav = [ - {file = "mkdocs_literate_nav-0.6.0-py3-none-any.whl", hash = "sha256:8c1b84714e5974da5e44e011ec0069275ae7647270c13a679662cf6ffce675a4"}, - {file = "mkdocs_literate_nav-0.6.0.tar.gz", hash = "sha256:81ccbea18163ae8e10bd0bd39237fe70c32a1f2dff6c170779f5d52dd98a0470"}, -] -mkdocs-material = [ - {file = "mkdocs_material-9.1.11-py3-none-any.whl", hash = "sha256:fbc86d50ec2cf34d40d5c4365780f290ceedde23f1a0704323b34e7f16b0c0dd"}, - {file = "mkdocs_material-9.1.11.tar.gz", hash = "sha256:f5d473eb79d6640a5e668d4b2ab5b9de5e76ae0a0e2d864112df0cfe9016dc1d"}, -] -mkdocs-material-extensions = [ - {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, - {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, -] -mkdocstrings = [ - {file = "mkdocstrings-0.21.2-py3-none-any.whl", hash = "sha256:949ef8da92df9d692ca07be50616459a6b536083a25520fd54b00e8814ce019b"}, - {file = "mkdocstrings-0.21.2.tar.gz", hash = "sha256:304e56a2e90595708a38a13a278e538a67ad82052dd5c8b71f77a604a4f3d911"}, -] -mkdocstrings-python = [ - {file = "mkdocstrings_python-1.0.0-py3-none-any.whl", hash = "sha256:c59d67009a7a85172f4da990d8523e95606b6a1ff93a22a2351ad3b5f8cafed1"}, - {file = "mkdocstrings_python-1.0.0.tar.gz", hash = "sha256:b89d849df990204f909d5452548b6936a185f912da06208a93909bebe25d6e67"}, -] -mknotebooks = [ - {file = "mknotebooks-0.7.1-py3-none-any.whl", hash = "sha256:e2fa000b706683fc56b93adada7190a0da22ad85c4f1bfd5c4468cc3552b78e5"}, -] -mktestdocs = [ - {file = "mktestdocs-0.2.1-py2.py3-none-any.whl", hash = "sha256:55ad757e83227d5ba217eb285b8e44dc490601c4bbef52bc3331fea4510b72ec"}, - {file = "mktestdocs-0.2.1.tar.gz", hash = "sha256:44142b98223f02c7ba4629790d9ee83031fd4d8855577c6fbfc23103421d3872"}, -] -ml-dtypes = [ - {file = "ml_dtypes-0.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:377f2d5cfbf809b59188e0bfda4a0774e658541f575b637fee4850d99c2f9fdc"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87aa1cf83d41fed5a40fc27ee57ac4c1bf904e940f082531d3d58f1c318b5928"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee8ea629b8e3e20c6649852c1b9deacfa13384ab9337f2c9e717e401d102f23"}, - {file = "ml_dtypes-0.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad765159ac6c18d5ee7d325fcf34d3106a9d9d7a49713d998f5cfa330a1459b4"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b9c5578dffd85637a7dd437192de18bc1a14eb6ba7d53ef40de3f84c51c789e5"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e8518c8fd2c38729f020125f39ef07b045f5c16d0846320c7252d7773285ee"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99fab8262d175c49bf1655c229244f301274e8289449c350ba4d5b95ade07d9a"}, - {file = "ml_dtypes-0.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8de9bbf5bed587a1166699447ea14d1e8fe66d4e812811e37bf2f4d988475476"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a29fbf128583673eca0f43def1dbe77e02c1e8b8a8331db2877bbb57d091ef11"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273c306db846005b83a98c9c7ec3dc8fa20e8f11c3772c8e8c20cc12d8abfd4b"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41b6beeaea47e2466b94068664c9a45b2a65dd023aa4e5deeb5a73303661344e"}, - {file = "ml_dtypes-0.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2de6c81b0da398d54aabdd7de599f2dfc43e30b65d9fad379a69f4cc4ae165d3"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:77970beeb3cf6ac559c4b6b393f24778a5abd34fafbaad82d5a0d17d0f148936"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffb7882dd46399217dc54f37affc899e0a29a4cfb63e5bf733ac0baf4a179c77"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5c9fe086756fbc1bf51296431d64429536093cf6e2ba592e042d7fc07c8514"}, - {file = "ml_dtypes-0.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9218175b06764b8ddc95cb18d11a6c4b48a4b103a31c9ea2b2c3cd0cfc369f8"}, - {file = "ml_dtypes-0.1.0.tar.gz", hash = "sha256:c1fc0afe63ce99069f9d7e0693a61cfd0aea90241fc3821af9953d0c11f4048a"}, -] -msgpack = [ - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, - {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, - {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, - {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, - {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, - {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, - {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, - {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, - {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, - {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, - {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, - {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, - {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, - {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, - {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, - {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, -] -multidict = [ - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, - {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, - {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, - {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, - {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, - {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, - {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, - {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, - {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, - {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, - {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, - {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, - {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, -] -munch = [ - {file = "munch-2.5.0-py2.py3-none-any.whl", hash = "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd"}, - {file = "munch-2.5.0.tar.gz", hash = "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2"}, -] -mypy-extensions = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] -nbclient = [ - {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, - {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, -] -nbconvert = [ - {file = "nbconvert-7.4.0-py3-none-any.whl", hash = "sha256:af5064a9db524f9f12f4e8be7f0799524bd5b14c1adea37e34e83c95127cc818"}, - {file = "nbconvert-7.4.0.tar.gz", hash = "sha256:51b6c77b507b177b73f6729dba15676e42c4e92bcb00edc8cc982ee72e7d89d7"}, -] -nbformat = [ - {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, - {file = "nbformat-5.8.0.tar.gz", hash = "sha256:46dac64c781f1c34dfd8acba16547024110348f9fc7eab0f31981c2a3dc48d1f"}, -] -nbstripout = [ - {file = "nbstripout-0.6.1-py2.py3-none-any.whl", hash = "sha256:5ff6eb0debbcd656c4a64db8e082a24fabcfc753a9e8c9f6d786971e8f29e110"}, - {file = "nbstripout-0.6.1.tar.gz", hash = "sha256:9065bcdd1488b386e4f3c081ffc1d48f4513a2f8d8bf4d0d9a28208c5dafe9d3"}, -] -nest-asyncio = [ - {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, - {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"}, -] -networkx = [ - {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, - {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, -] -nodeenv = [ - {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, - {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, -] -nox = [ - {file = "nox-2022.11.21-py3-none-any.whl", hash = "sha256:0e41a990e290e274cb205a976c4c97ee3c5234441a8132c8c3fd9ea3c22149eb"}, - {file = "nox-2022.11.21.tar.gz", hash = "sha256:e21c31de0711d1274ca585a2c5fde36b1aa962005ba8e9322bf5eeed16dcd684"}, -] -numpy = [ - {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, - {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, - {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, - {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, - {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, - {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, - {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, - {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, - {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, - {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, - {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, -] -opt-einsum = [ - {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, - {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, -] -optax = [ - {file = "optax-0.1.5-py3-none-any.whl", hash = "sha256:4057461448abd1fccdefd5e6c7ebc6ea8daa3105041f2631d6efd506544ecde0"}, - {file = "optax-0.1.5.tar.gz", hash = "sha256:0aa379b56f51dbd525562f5ee6805a180a2616f3e9fe8080582352bcbb520f2e"}, -] -orbax-checkpoint = [ - {file = "orbax-checkpoint-0.2.3.tar.gz", hash = "sha256:155e0a2dceef2901122e66585171e1dff4f4a4d9d2abe43a2b514279b9a3dabd"}, - {file = "orbax_checkpoint-0.2.3-py3-none-any.whl", hash = "sha256:a001bf48f1cebc635b07263fa546473ea48be3e278c50d5ade880b9aafb96f8a"}, -] -packaging = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, -] -pandas = [ - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, - {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, - {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, - {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, - {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, - {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, - {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, - {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, -] -pandocfilters = [ - {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, - {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, -] -parso = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] -pathlib2 = [ - {file = "pathlib2-2.3.7.post1-py2.py3-none-any.whl", hash = "sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b"}, - {file = "pathlib2-2.3.7.post1.tar.gz", hash = "sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641"}, -] -pathspec = [ - {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, - {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, -] -pexpect = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] -pickleshare = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] -pillow = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, -] -pkgutil-resolve-name = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] -planetary-computer = [ - {file = "planetary-computer-0.5.1.tar.gz", hash = "sha256:a46de4a6bab359a5b691f2059f5dbe842c92b45390b5f1ab465bdf2819008d35"}, - {file = "planetary_computer-0.5.1-py3-none-any.whl", hash = "sha256:87cd7b89a8df33b71aab3a05b390ecedd3830ece1bb3ad33725019db30c9683f"}, -] -platformdirs = [ - {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, - {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -plum-dispatch = [ - {file = "plum_dispatch-2.1.0-py3-none-any.whl", hash = "sha256:a1f2880b54507b84254a0423fefce4001b50f16c9f870bfea3892cb279061508"}, - {file = "plum_dispatch-2.1.0.tar.gz", hash = "sha256:7c13a29f23b2a225f04780f7d054562c95c6e1db251f9e5fc5325dbaecaa2567"}, -] -pre-commit = [ - {file = "pre_commit-3.3.1-py2.py3-none-any.whl", hash = "sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9"}, - {file = "pre_commit-3.3.1.tar.gz", hash = "sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907"}, -] -prompt-toolkit = [ - {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, - {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, -] -psutil = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, -] -ptyprocess = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] -pure-eval = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pybtex = [ - {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, - {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, -] -pycparser = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] -pydantic = [ - {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, - {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, - {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, - {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, - {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, - {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, - {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, - {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, - {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, - {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, -] -pydocstyle = [ - {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, - {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, -] -pygments = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, -] -pylint = [ - {file = "pylint-2.17.4-py3-none-any.whl", hash = "sha256:7a1145fb08c251bdb5cca11739722ce64a63db479283d10ce718b2460e54123c"}, - {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, -] -pymdown-extensions = [ - {file = "pymdown_extensions-9.11-py3-none-any.whl", hash = "sha256:a499191d8d869f30339de86fcf072a787e86c42b6f16f280f5c2cf174182b7f3"}, - {file = "pymdown_extensions-9.11.tar.gz", hash = "sha256:f7e86c1d3981f23d9dc43294488ecb54abadd05b0be4bf8f0e15efc90f7853ff"}, -] -pympler = [ - {file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"}, - {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, -] -pypandoc = [ - {file = "pypandoc-1.11-py3-none-any.whl", hash = "sha256:b260596934e9cfc6513056110a7c8600171d414f90558bf4407e68b209be8007"}, - {file = "pypandoc-1.11.tar.gz", hash = "sha256:7f6d68db0e57e0f6961bec2190897118c4d305fc2d31c22cd16037f22ee084a5"}, -] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] -pyproj = [ - {file = "pyproj-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6475ce653880938468a1a1b7321267243909e34b972ba9e53d5982c41d555918"}, - {file = "pyproj-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61e4ad57d89b03a7b173793b31bca8ee110112cde1937ef0f42a70b9120c827d"}, - {file = "pyproj-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdd2021bb6f7f346bfe1d2a358aa109da017d22c4704af2d994e7c7ee0a7a53"}, - {file = "pyproj-3.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5674923351e76222e2c10c58b5e1ac119d7a46b270d822c463035971b06f724b"}, - {file = "pyproj-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd5e2b6aa255023c4acd0b977590f1f7cc801ba21b4d806fcf6dfac3474ebb83"}, - {file = "pyproj-3.5.0-cp310-cp310-win32.whl", hash = "sha256:6f316a66031a14e9c5a88c91f8b77aa97f5454895674541ed6ab630b682be35d"}, - {file = "pyproj-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:f7c2f4d9681e810cf40239caaca00079930a6d9ee6591139b88d592d36051d82"}, - {file = "pyproj-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7572983134e310e0ca809c63f1722557a040fe9443df5f247bf11ba887eb1229"}, - {file = "pyproj-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eccb417b91d0be27805dfc97550bfb8b7db94e9fe1db5ebedb98f5b88d601323"}, - {file = "pyproj-3.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:621d78a9d8bf4d06e08bef2471021fbcb1a65aa629ad4a20c22e521ce729cc20"}, - {file = "pyproj-3.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9a024370e917c899bff9171f03ea6079deecdc7482a146a2c565f3b9df134ea"}, - {file = "pyproj-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b7c2113c4d11184a238077ec85e31eda1dcc58ffeb9a4429830e0a7036e787d"}, - {file = "pyproj-3.5.0-cp311-cp311-win32.whl", hash = "sha256:a730f5b4c98c8a0f312437873e6e34dbd4cc6dc23d5afd91a6691c62724b1f68"}, - {file = "pyproj-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:e97573de0ab3bbbcb4c7748bc41f4ceb6da10b45d35b1a294b5820701e7c25f0"}, - {file = "pyproj-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2b708fd43453b985642b737d4a6e7f1d6a0ab1677ffa4e14cc258537b49224b0"}, - {file = "pyproj-3.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b60d93a200639e8367c6542a964fd0aa2dbd152f256c1831dc18cd5aa470fb8a"}, - {file = "pyproj-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38862fe07316ae12b79d82d298e390973a4f00b684f3c2d037238e20e00610ba"}, - {file = "pyproj-3.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b65f2a38cd9e16883dbb0f8ae82bdf8f6b79b1b02975c78483ab8428dbbf2f"}, - {file = "pyproj-3.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b752b7d9c4b08181c7e8c0d9c7f277cbefff42227f34d3310696a87c863d9dd3"}, - {file = "pyproj-3.5.0-cp38-cp38-win32.whl", hash = "sha256:b937215bfbaf404ec8f03ca741fc3f9f2c4c2c5590a02ccddddd820ae3c71331"}, - {file = "pyproj-3.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:97ed199033c2c770e7eea2ef80ff5e6413426ec2d7ec985b869792f04ab95d05"}, - {file = "pyproj-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:052c49fce8b5d55943a35c36ccecb87350c68b48ba95bc02a789770c374ef819"}, - {file = "pyproj-3.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1507138ea28bf2134d31797675380791cc1a7156a3aeda484e65a78a4aba9b62"}, - {file = "pyproj-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02742ef3d846401861a878a61ef7ad911ea7539d6cc4619ddb52dbdf7b45aee"}, - {file = "pyproj-3.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:385b0341861d3ebc8cad98337a738821dcb548d465576527399f4955ca24b6ed"}, - {file = "pyproj-3.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fe6bb1b68a35d07378d38be77b5b2f8dd2bea5910c957bfcc7bee55988d3910"}, - {file = "pyproj-3.5.0-cp39-cp39-win32.whl", hash = "sha256:5c4b85ac10d733c42d73a2e6261c8d6745bf52433a31848dd1b6561c9a382da3"}, - {file = "pyproj-3.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:1798ff7d65d9057ebb2d017ffe8403268b8452f24d0428b2140018c25c7fa1bc"}, - {file = "pyproj-3.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d711517a8487ef3245b08dc82f781a906df9abb3b6cb0ce0486f0eeb823ca570"}, - {file = "pyproj-3.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788a5dadb532644a64efe0f5f01bf508c821eb7e984f13a677d56002f1e8a67a"}, - {file = "pyproj-3.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73f7960a97225812f9b1d7aeda5fb83812f38de9441e3476fcc8abb3e2b2f4de"}, - {file = "pyproj-3.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fde5ece4d2436b5a57c8f5f97b49b5de06a856d03959f836c957d3e609f2de7e"}, - {file = "pyproj-3.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e08db25b61cf024648d55973cc3d1c3f1d0818fabf594d5f5a8e2318103d2aa0"}, - {file = "pyproj-3.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a87b419a2a352413fbf759ecb66da9da50bd19861c8f26db6a25439125b27b9"}, - {file = "pyproj-3.5.0.tar.gz", hash = "sha256:9859d1591c1863414d875ae0759e72c2cffc01ab989dc64137fbac572cc81bf6"}, -] -pyrsistent = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] -pystac = [ - {file = "pystac-1.7.3-py3-none-any.whl", hash = "sha256:2b1b5e11b995e443376ca1d195609d95723f690c8d192604bc00091fcdf52e4c"}, - {file = "pystac-1.7.3.tar.gz", hash = "sha256:6848074fad6665ac631abd62c692bb868de37379615db90f4d913dca37f844ce"}, -] -pystac-client = [ - {file = "pystac-client-0.6.1.tar.gz", hash = "sha256:1981537ad0fd167b08790eb3f41e7c2788438f461125b42b47bc934eaf1adcb1"}, - {file = "pystac_client-0.6.1-py3-none-any.whl", hash = "sha256:124d81bd9653b3e12c7ff244bf0dad420cadeaf86ab394dfdc804958ff723fcd"}, -] -pytest = [ - {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, - {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, -] -pytest-cov = [ - {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, - {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, -] -pytest-pretty = [ - {file = "pytest_pretty-1.2.0-py3-none-any.whl", hash = "sha256:6f79122bf53864ae2951b6c9e94d7a06a87ef753476acd4588aeac018f062036"}, - {file = "pytest_pretty-1.2.0.tar.gz", hash = "sha256:105a355f128e392860ad2c478ae173ff96d2f03044692f9818ff3d49205d3a60"}, -] -pytest-xdist = [ - {file = "pytest-xdist-3.2.1.tar.gz", hash = "sha256:1849bd98d8b242b948e472db7478e090bf3361912a8fed87992ed94085f54727"}, - {file = "pytest_xdist-3.2.1-py3-none-any.whl", hash = "sha256:37290d161638a20b672401deef1cba812d110ac27e35d213f091d15b8beb40c9"}, -] -python-dateutil = [ - {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"}, -] -python-dotenv = [ - {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, - {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, -] -pytkdocs = [ - {file = "pytkdocs-0.16.1-py3-none-any.whl", hash = "sha256:a8c3f46ecef0b92864cc598e9101e9c4cf832ebbf228f50c84aa5dd850aac379"}, - {file = "pytkdocs-0.16.1.tar.gz", hash = "sha256:e2ccf6dfe9dbbceb09818673f040f1a7c32ed0bffb2d709b06be6453c4026045"}, -] -pytz = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, -] -pywin32 = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] -pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] -pyyaml-env-tag = [ - {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, - {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, -] -pyzmq = [ - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ac178e666c097c8d3deb5097b58cd1316092fc43e8ef5b5fdb259b51da7e7315"}, - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:659e62e1cbb063151c52f5b01a38e1df6b54feccfa3e2509d44c35ca6d7962ee"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8280ada89010735a12b968ec3ea9a468ac2e04fddcc1cede59cb7f5178783b9c"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b5eeb5278a8a636bb0abdd9ff5076bcbb836cd2302565df53ff1fa7d106d54"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a2e5fe42dfe6b73ca120b97ac9f34bfa8414feb15e00e37415dbd51cf227ef6"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:827bf60e749e78acb408a6c5af6688efbc9993e44ecc792b036ec2f4b4acf485"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7b504ae43d37e282301da586529e2ded8b36d4ee2cd5e6db4386724ddeaa6bbc"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb1f69a0a2a2b1aae8412979dd6293cc6bcddd4439bf07e4758d864ddb112354"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b9c9cc965cdf28381e36da525dcb89fc1571d9c54800fdcd73e3f73a2fc29bd"}, - {file = "pyzmq-25.0.2-cp310-cp310-win32.whl", hash = "sha256:24abbfdbb75ac5039205e72d6c75f10fc39d925f2df8ff21ebc74179488ebfca"}, - {file = "pyzmq-25.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a821a506822fac55d2df2085a52530f68ab15ceed12d63539adc32bd4410f6e"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9af0bb0277e92f41af35e991c242c9c71920169d6aa53ade7e444f338f4c8128"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54a96cf77684a3a537b76acfa7237b1e79a8f8d14e7f00e0171a94b346c5293e"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88649b19ede1cab03b96b66c364cbbf17c953615cdbc844f7f6e5f14c5e5261c"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:715cff7644a80a7795953c11b067a75f16eb9fc695a5a53316891ebee7f3c9d5"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b3f0f066b4f1d17383aae509bacf833ccaf591184a1f3c7a1661c085063ae"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d488c5c8630f7e782e800869f82744c3aca4aca62c63232e5d8c490d3d66956a"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:38d9f78d69bcdeec0c11e0feb3bc70f36f9b8c44fc06e5d06d91dc0a21b453c7"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3059a6a534c910e1d5d068df42f60d434f79e6cc6285aa469b384fa921f78cf8"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6526d097b75192f228c09d48420854d53dfbc7abbb41b0e26f363ccb26fbc177"}, - {file = "pyzmq-25.0.2-cp311-cp311-win32.whl", hash = "sha256:5c5fbb229e40a89a2fe73d0c1181916f31e30f253cb2d6d91bea7927c2e18413"}, - {file = "pyzmq-25.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed15e3a2c3c2398e6ae5ce86d6a31b452dfd6ad4cd5d312596b30929c4b6e182"}, - {file = "pyzmq-25.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:032f5c8483c85bf9c9ca0593a11c7c749d734ce68d435e38c3f72e759b98b3c9"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:374b55516393bfd4d7a7daa6c3b36d6dd6a31ff9d2adad0838cd6a203125e714"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08bfcc21b5997a9be4fefa405341320d8e7f19b4d684fb9c0580255c5bd6d695"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1a843d26a8da1b752c74bc019c7b20e6791ee813cd6877449e6a1415589d22ff"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b48616a09d7df9dbae2f45a0256eee7b794b903ddc6d8657a9948669b345f220"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d4427b4a136e3b7f85516c76dd2e0756c22eec4026afb76ca1397152b0ca8145"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:26b0358e8933990502f4513c991c9935b6c06af01787a36d133b7c39b1df37fa"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win32.whl", hash = "sha256:c8fedc3ccd62c6b77dfe6f43802057a803a411ee96f14e946f4a76ec4ed0e117"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2da6813b7995b6b1d1307329c73d3e3be2fd2d78e19acfc4eff2e27262732388"}, - {file = "pyzmq-25.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a35960c8b2f63e4ef67fd6731851030df68e4b617a6715dd11b4b10312d19fef"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2a0b880ab40aca5a878933376cb6c1ec483fba72f7f34e015c0f675c90b20"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:85762712b74c7bd18e340c3639d1bf2f23735a998d63f46bb6584d904b5e401d"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:64812f29d6eee565e129ca14b0c785744bfff679a4727137484101b34602d1a7"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:510d8e55b3a7cd13f8d3e9121edf0a8730b87d925d25298bace29a7e7bc82810"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b164cc3c8acb3d102e311f2eb6f3c305865ecb377e56adc015cb51f721f1dda6"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:28fdb9224a258134784a9cf009b59265a9dde79582fb750d4e88a6bcbc6fa3dc"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win32.whl", hash = "sha256:dd771a440effa1c36d3523bc6ba4e54ff5d2e54b4adcc1e060d8f3ca3721d228"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:9bdc40efb679b9dcc39c06d25629e55581e4c4f7870a5e88db4f1c51ce25e20d"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:1f82906a2d8e4ee310f30487b165e7cc8ed09c009e4502da67178b03083c4ce0"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21ec0bf4831988af43c8d66ba3ccd81af2c5e793e1bf6790eb2d50e27b3c570a"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbce982a17c88d2312ec2cf7673985d444f1beaac6e8189424e0a0e0448dbb3"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e1d2f2d86fc75ed7f8845a992c5f6f1ab5db99747fb0d78b5e4046d041164d2"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e92ff20ad5d13266bc999a29ed29a3b5b101c21fdf4b2cf420c09db9fb690e"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edbbf06cc2719889470a8d2bf5072bb00f423e12de0eb9ffec946c2c9748e149"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77942243ff4d14d90c11b2afd8ee6c039b45a0be4e53fb6fa7f5e4fd0b59da39"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ab046e9cb902d1f62c9cc0eca055b1d11108bdc271caf7c2171487298f229b56"}, - {file = "pyzmq-25.0.2-cp38-cp38-win32.whl", hash = "sha256:ad761cfbe477236802a7ab2c080d268c95e784fe30cafa7e055aacd1ca877eb0"}, - {file = "pyzmq-25.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8560756318ec7c4c49d2c341012167e704b5a46d9034905853c3d1ade4f55bee"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ab2c056ac503f25a63f6c8c6771373e2a711b98b304614151dfb552d3d6c81f6"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cca8524b61c0eaaa3505382dc9b9a3bc8165f1d6c010fdd1452c224225a26689"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb9f7eae02d3ac42fbedad30006b7407c984a0eb4189a1322241a20944d61e5"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5eaeae038c68748082137d6896d5c4db7927e9349237ded08ee1bbd94f7361c9"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a31992a8f8d51663ebf79df0df6a04ffb905063083d682d4380ab8d2c67257c"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6a979e59d2184a0c8f2ede4b0810cbdd86b64d99d9cc8a023929e40dce7c86cc"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1f124cb73f1aa6654d31b183810febc8505fd0c597afa127c4f40076be4574e0"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:65c19a63b4a83ae45d62178b70223adeee5f12f3032726b897431b6553aa25af"}, - {file = "pyzmq-25.0.2-cp39-cp39-win32.whl", hash = "sha256:83d822e8687621bed87404afc1c03d83fa2ce39733d54c2fd52d8829edb8a7ff"}, - {file = "pyzmq-25.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:24683285cc6b7bf18ad37d75b9db0e0fefe58404e7001f1d82bf9e721806daa7"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a4b4261eb8f9ed71f63b9eb0198dd7c934aa3b3972dac586d0ef502ba9ab08b"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:62ec8d979f56c0053a92b2b6a10ff54b9ec8a4f187db2b6ec31ee3dd6d3ca6e2"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:affec1470351178e892121b3414c8ef7803269f207bf9bef85f9a6dd11cde264"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc71111433bd6ec8607a37b9211f4ef42e3d3b271c6d76c813669834764b248"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6fadc60970714d86eff27821f8fb01f8328dd36bebd496b0564a500fe4a9e354"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:269968f2a76c0513490aeb3ba0dc3c77b7c7a11daa894f9d1da88d4a0db09835"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f7c8b8368e84381ae7c57f1f5283b029c888504aaf4949c32e6e6fb256ec9bf0"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25e6873a70ad5aa31e4a7c41e5e8c709296edef4a92313e1cd5fc87bbd1874e2"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b733076ff46e7db5504c5e7284f04a9852c63214c74688bdb6135808531755a3"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a6f6ae12478fdc26a6d5fdb21f806b08fa5403cd02fd312e4cb5f72df078f96f"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:67da1c213fbd208906ab3470cfff1ee0048838365135a9bddc7b40b11e6d6c89"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531e36d9fcd66f18de27434a25b51d137eb546931033f392e85674c7a7cea853"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34a6fddd159ff38aa9497b2e342a559f142ab365576284bc8f77cb3ead1f79c5"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b491998ef886662c1f3d49ea2198055a9a536ddf7430b051b21054f2a5831800"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5d496815074e3e3d183fe2c7fcea2109ad67b74084c254481f87b64e04e9a471"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:56a94ab1d12af982b55ca96c6853db6ac85505e820d9458ac76364c1998972f4"}, - {file = "pyzmq-25.0.2.tar.gz", hash = "sha256:6b8c1bbb70e868dc88801aa532cae6bd4e3b5233784692b786f17ad2962e5149"}, -] -rasterio = [ - {file = "rasterio-1.3.6-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:23a8d10ba17301029962a5667915381a8b4711ed80b712eb71cf68834cb5f946"}, - {file = "rasterio-1.3.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76b6bd4b566cd733f0ddd05ba88bea3f96705ff74e2e5fab73ead2a26cbc5979"}, - {file = "rasterio-1.3.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50785004d7adf66cf96c9c3498cf530ec91292e9349e66e8d1f1183085ee93b1"}, - {file = "rasterio-1.3.6-cp310-cp310-win_amd64.whl", hash = "sha256:9f3f901097c3f306f1143d6fdc503440596c66a2c39054e25604bdf3f4eaaff3"}, - {file = "rasterio-1.3.6-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:a732f8d314b7d9cb532b1969e968d08bf208886f04309662a5d16884af39bb4a"}, - {file = "rasterio-1.3.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d03e2fcd8f3aafb0ea1fa27a021fecc385655630a46c70d6ba693675c6cc3830"}, - {file = "rasterio-1.3.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69fdc712e9c79e82d00d783d23034bb16ca8faa18856e83e297bb7e4d7e3e277"}, - {file = "rasterio-1.3.6-cp311-cp311-win_amd64.whl", hash = "sha256:83f764c2b30e3d07bea5626392f1ce5481e61d5583256ab66f3a610a2f40dec7"}, - {file = "rasterio-1.3.6-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:1321372c653a36928b4e5e11cbe7f851903fb76608b8e48a860168b248d5f8e6"}, - {file = "rasterio-1.3.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8a584fedd92953a0580e8de3f41ce9f33a3205ba79ea58fff8f90ba5d14a0c04"}, - {file = "rasterio-1.3.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92f0f92254fcce57d25d5f60ef2cf649297f8a1e1fa279b32795bde20f11ff41"}, - {file = "rasterio-1.3.6-cp38-cp38-win_amd64.whl", hash = "sha256:e73339e8fb9b9091a4a0ffd9f84725b2d1f118cf51c35fb0d03b94e82e1736a3"}, - {file = "rasterio-1.3.6-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:eaaeb2e661d1ffc07a7ae4fd997bb326d3561f641178126102842d608a010cc3"}, - {file = "rasterio-1.3.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0883a38bd32e6a3d8d85bac67e3b75a2f04f7de265803585516883223ddbb8d1"}, - {file = "rasterio-1.3.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b72fc032ddca55d73de87ef3872530b7384989378a1bc66d77c69cedafe7feaf"}, - {file = "rasterio-1.3.6-cp39-cp39-win_amd64.whl", hash = "sha256:cb3288add5d55248f5d48815f9d509819ba8985cd0302d2e8dd743f83c5ec96d"}, - {file = "rasterio-1.3.6.tar.gz", hash = "sha256:c8b90eb10e16102d1ab0334a7436185f295de1c07f0d197e206d1c005fc33905"}, -] -regex = [ - {file = "regex-2023.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:48c9ec56579d4ba1c88f42302194b8ae2350265cb60c64b7b9a88dcb7fbde309"}, - {file = "regex-2023.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f4541550459c08fdd6f97aa4e24c6f1932eec780d58a2faa2068253df7d6ff"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e22e4460f0245b468ee645156a4f84d0fc35a12d9ba79bd7d79bdcd2f9629d"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b870b6f632fc74941cadc2a0f3064ed8409e6f8ee226cdfd2a85ae50473aa94"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:171c52e320fe29260da550d81c6b99f6f8402450dc7777ef5ced2e848f3b6f8f"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad5524c2aedaf9aa14ef1bc9327f8abd915699dea457d339bebbe2f0d218f86"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a0f874ee8c0bc820e649c900243c6d1e6dc435b81da1492046716f14f1a2a96"}, - {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e645c757183ee0e13f0bbe56508598e2d9cd42b8abc6c0599d53b0d0b8dd1479"}, - {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a4c5da39bca4f7979eefcbb36efea04471cd68db2d38fcbb4ee2c6d440699833"}, - {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5e3f4468b8c6fd2fd33c218bbd0a1559e6a6fcf185af8bb0cc43f3b5bfb7d636"}, - {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:59e4b729eae1a0919f9e4c0fc635fbcc9db59c74ad98d684f4877be3d2607dd6"}, - {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ba73a14e9c8f9ac409863543cde3290dba39098fc261f717dc337ea72d3ebad2"}, - {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bbd5dcb19603ab8d2781fac60114fb89aee8494f4505ae7ad141a3314abb1f9"}, - {file = "regex-2023.5.5-cp310-cp310-win32.whl", hash = "sha256:40005cbd383438aecf715a7b47fe1e3dcbc889a36461ed416bdec07e0ef1db66"}, - {file = "regex-2023.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:59597cd6315d3439ed4b074febe84a439c33928dd34396941b4d377692eca810"}, - {file = "regex-2023.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f08276466fedb9e36e5193a96cb944928301152879ec20c2d723d1031cd4ddd"}, - {file = "regex-2023.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cd46f30e758629c3ee91713529cfbe107ac50d27110fdcc326a42ce2acf4dafc"}, - {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2910502f718828cecc8beff004917dcf577fc5f8f5dd40ffb1ea7612124547b"}, - {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:445d6f4fc3bd9fc2bf0416164454f90acab8858cd5a041403d7a11e3356980e8"}, - {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18196c16a584619c7c1d843497c069955d7629ad4a3fdee240eb347f4a2c9dbe"}, - {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33d430a23b661629661f1fe8395be2004006bc792bb9fc7c53911d661b69dd7e"}, - {file = "regex-2023.5.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72a28979cc667e5f82ef433db009184e7ac277844eea0f7f4d254b789517941d"}, - {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f764e4dfafa288e2eba21231f455d209f4709436baeebb05bdecfb5d8ddc3d35"}, - {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23d86ad2121b3c4fc78c58f95e19173790e22ac05996df69b84e12da5816cb17"}, - {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:690a17db524ee6ac4a27efc5406530dd90e7a7a69d8360235323d0e5dafb8f5b"}, - {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1ecf3dcff71f0c0fe3e555201cbe749fa66aae8d18f80d2cc4de8e66df37390a"}, - {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:811040d7f3dd9c55eb0d8b00b5dcb7fd9ae1761c454f444fd9f37fe5ec57143a"}, - {file = "regex-2023.5.5-cp311-cp311-win32.whl", hash = "sha256:c8c143a65ce3ca42e54d8e6fcaf465b6b672ed1c6c90022794a802fb93105d22"}, - {file = "regex-2023.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:586a011f77f8a2da4b888774174cd266e69e917a67ba072c7fc0e91878178a80"}, - {file = "regex-2023.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b6365703e8cf1644b82104cdd05270d1a9f043119a168d66c55684b1b557d008"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a56c18f21ac98209da9c54ae3ebb3b6f6e772038681d6cb43b8d53da3b09ee81"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b942d8b3ce765dbc3b1dad0a944712a89b5de290ce8f72681e22b3c55f3cc8"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:844671c9c1150fcdac46d43198364034b961bd520f2c4fdaabfc7c7d7138a2dd"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2ce65bdeaf0a386bb3b533a28de3994e8e13b464ac15e1e67e4603dd88787fa"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fee0016cc35a8a91e8cc9312ab26a6fe638d484131a7afa79e1ce6165328a135"}, - {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18f05d14f14a812fe9723f13afafefe6b74ca042d99f8884e62dbd34dcccf3e2"}, - {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:941b3f1b2392f0bcd6abf1bc7a322787d6db4e7457be6d1ffd3a693426a755f2"}, - {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:921473a93bcea4d00295799ab929522fc650e85c6b9f27ae1e6bb32a790ea7d3"}, - {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:e2205a81f815b5bb17e46e74cc946c575b484e5f0acfcb805fb252d67e22938d"}, - {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:385992d5ecf1a93cb85adff2f73e0402dd9ac29b71b7006d342cc920816e6f32"}, - {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:890a09cb0a62198bff92eda98b2b507305dd3abf974778bae3287f98b48907d3"}, - {file = "regex-2023.5.5-cp36-cp36m-win32.whl", hash = "sha256:821a88b878b6589c5068f4cc2cfeb2c64e343a196bc9d7ac68ea8c2a776acd46"}, - {file = "regex-2023.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:7918a1b83dd70dc04ab5ed24c78ae833ae8ea228cef84e08597c408286edc926"}, - {file = "regex-2023.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:338994d3d4ca4cf12f09822e025731a5bdd3a37aaa571fa52659e85ca793fb67"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a69cf0c00c4d4a929c6c7717fd918414cab0d6132a49a6d8fc3ded1988ed2ea"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f5e06df94fff8c4c85f98c6487f6636848e1dc85ce17ab7d1931df4a081f657"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8906669b03c63266b6a7693d1f487b02647beb12adea20f8840c1a087e2dfb5"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fda3e50abad8d0f48df621cf75adc73c63f7243cbe0e3b2171392b445401550"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ac2b7d341dc1bd102be849d6dd33b09701223a851105b2754339e390be0627a"}, - {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2b495dd94b02de8215625948132cc2ea360ae84fe6634cd19b6567709c8ae2"}, - {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aa7d032c1d84726aa9edeb6accf079b4caa87151ca9fabacef31fa028186c66d"}, - {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d45864693351c15531f7e76f545ec35000d50848daa833cead96edae1665559"}, - {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21e90a288e6ba4bf44c25c6a946cb9b0f00b73044d74308b5e0afd190338297c"}, - {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:10250a093741ec7bf74bcd2039e697f519b028518f605ff2aa7ac1e9c9f97423"}, - {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6b8d0c153f07a953636b9cdb3011b733cadd4178123ef728ccc4d5969e67f3c2"}, - {file = "regex-2023.5.5-cp37-cp37m-win32.whl", hash = "sha256:10374c84ee58c44575b667310d5bbfa89fb2e64e52349720a0182c0017512f6c"}, - {file = "regex-2023.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9b320677521aabf666cdd6e99baee4fb5ac3996349c3b7f8e7c4eee1c00dfe3a"}, - {file = "regex-2023.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:afb1c70ec1e594a547f38ad6bf5e3d60304ce7539e677c1429eebab115bce56e"}, - {file = "regex-2023.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf123225945aa58b3057d0fba67e8061c62d14cc8a4202630f8057df70189051"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99757ad7fe5c8a2bb44829fc57ced11253e10f462233c1255fe03888e06bc19"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a623564d810e7a953ff1357f7799c14bc9beeab699aacc8b7ab7822da1e952b8"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ced02e3bd55e16e89c08bbc8128cff0884d96e7f7a5633d3dc366b6d95fcd1d6"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cbe6b5be3b9b698d8cc4ee4dee7e017ad655e83361cd0ea8e653d65e469468"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a6e4b0e0531223f53bad07ddf733af490ba2b8367f62342b92b39b29f72735a"}, - {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e9c4f778514a560a9c9aa8e5538bee759b55f6c1dcd35613ad72523fd9175b8"}, - {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:256f7f4c6ba145f62f7a441a003c94b8b1af78cee2cccacfc1e835f93bc09426"}, - {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd7b68fd2e79d59d86dcbc1ccd6e2ca09c505343445daaa4e07f43c8a9cc34da"}, - {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4a5059bd585e9e9504ef9c07e4bc15b0a621ba20504388875d66b8b30a5c4d18"}, - {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6893544e06bae009916a5658ce7207e26ed17385149f35a3125f5259951f1bbe"}, - {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c64d5abe91a3dfe5ff250c6bb267ef00dbc01501518225b45a5f9def458f31fb"}, - {file = "regex-2023.5.5-cp38-cp38-win32.whl", hash = "sha256:7923470d6056a9590247ff729c05e8e0f06bbd4efa6569c916943cb2d9b68b91"}, - {file = "regex-2023.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:4035d6945cb961c90c3e1c1ca2feb526175bcfed44dfb1cc77db4fdced060d3e"}, - {file = "regex-2023.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50fd2d9b36938d4dcecbd684777dd12a407add4f9f934f235c66372e630772b0"}, - {file = "regex-2023.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d19e57f888b00cd04fc38f5e18d0efbd91ccba2d45039453ab2236e6eec48d4d"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd966475e963122ee0a7118ec9024388c602d12ac72860f6eea119a3928be053"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db09e6c18977a33fea26fe67b7a842f706c67cf8bda1450974d0ae0dd63570df"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6164d4e2a82f9ebd7752a06bd6c504791bedc6418c0196cd0a23afb7f3e12b2d"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84397d3f750d153ebd7f958efaa92b45fea170200e2df5e0e1fd4d85b7e3f58a"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c3efee9bb53cbe7b285760c81f28ac80dc15fa48b5fe7e58b52752e642553f1"}, - {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:144b5b017646b5a9392a5554a1e5db0000ae637be4971c9747566775fc96e1b2"}, - {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1189fbbb21e2c117fda5303653b61905aeeeea23de4a94d400b0487eb16d2d60"}, - {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f83fe9e10f9d0b6cf580564d4d23845b9d692e4c91bd8be57733958e4c602956"}, - {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:72aa4746993a28c841e05889f3f1b1e5d14df8d3daa157d6001a34c98102b393"}, - {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:de2f780c3242ea114dd01f84848655356af4dd561501896c751d7b885ea6d3a1"}, - {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:290fd35219486dfbc00b0de72f455ecdd63e59b528991a6aec9fdfc0ce85672e"}, - {file = "regex-2023.5.5-cp39-cp39-win32.whl", hash = "sha256:732176f5427e72fa2325b05c58ad0b45af341c459910d766f814b0584ac1f9ac"}, - {file = "regex-2023.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:1307aa4daa1cbb23823d8238e1f61292fd07e4e5d8d38a6efff00b67a7cdb764"}, - {file = "regex-2023.5.5.tar.gz", hash = "sha256:7d76a8a1fc9da08296462a18f16620ba73bcbf5909e42383b253ef34d9d5141e"}, -] -requests = [ - {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, - {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, -] -rich = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, -] -rioxarray = [ - {file = "rioxarray-0.13.4-py3-none-any.whl", hash = "sha256:56eef711d9817d3c729c1a267c940e7dff66bfc874a0b24ed3604ea2f958dfb2"}, - {file = "rioxarray-0.13.4.tar.gz", hash = "sha256:0cad24ad2c3c5ee181a0cfad2b8c2152a609b7eb118a3430034aec171e9cf14f"}, -] -ruff = [ - {file = "ruff-0.0.259-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f3938dc45e2a3f818e9cbd53007265c22246fbfded8837b2c563bf0ebde1a226"}, - {file = "ruff-0.0.259-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:22e1e35bf5f12072cd644d22afd9203641ccf258bc14ff91aa1c43dc14f6047d"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2fb20e89e85d147c85caa807707a1488bccc1f3854dc3d53533e89b52a0c5ff"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:49e903bcda19f6bb0725a962c058eb5d61f40d84ef52ed53b61939b69402ab4e"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71f0ef1985e9a6696fa97da8459917fa34bdaa2c16bd33bd5edead585b7d44f7"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7cfef26619cba184d59aa7fa17b48af5891d51fc0b755a9bc533478a10d4d066"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79b02fa17ec1fd8d306ae302cb47fb614b71e1f539997858243769bcbe78c6d9"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:428507fb321b386dda70d66cd1a8aa0abf51d7c197983d83bb9e4fa5ee60300b"}, - {file = "ruff-0.0.259-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fbaea9167f1852757f02133e5daacdb8c75b3431343205395da5b10499927a"}, - {file = "ruff-0.0.259-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:40ae87f2638484b7e8a7567b04a7af719f1c484c5bf132038b702bb32e1f6577"}, - {file = "ruff-0.0.259-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:29e2b77b7d5da6a7dd5cf9b738b511355c5734ece56f78e500d4b5bffd58c1a0"}, - {file = "ruff-0.0.259-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b3c1beacf6037e7f0781d4699d9a2dd4ba2462f475be5b1f45cf84c4ba3c69d"}, - {file = "ruff-0.0.259-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:daaea322e7e85f4c13d82be9536309e1c4b8b9851bb0cbc7eeb15d490fd46bf9"}, - {file = "ruff-0.0.259-py3-none-win32.whl", hash = "sha256:38704f151323aa5858370a2f792e122cc25e5d1aabe7d42ceeab83da18f0b456"}, - {file = "ruff-0.0.259-py3-none-win_amd64.whl", hash = "sha256:aa9449b898287e621942cc71b9327eceb8f0c357e4065fecefb707ef2d978df8"}, - {file = "ruff-0.0.259-py3-none-win_arm64.whl", hash = "sha256:e4f39e18702de69faaaee3969934b92d7467285627f99a5b6ecd55a7d9f5d086"}, - {file = "ruff-0.0.259.tar.gz", hash = "sha256:8b56496063ab3bfdf72339a5fbebb8bd46e5c5fee25ef11a9f03b208fa0562ec"}, -] -scikit-learn = [ - {file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7"}, - {file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f"}, - {file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb"}, - {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe83b676f407f00afa388dd1fdd49e5c6612e551ed84f3b1b182858f09e987d"}, - {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2642baa0ad1e8f8188917423dd73994bf25429f8893ddbe115be3ca3183584"}, - {file = "scikit_learn-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ad66c3848c0a1ec13464b2a95d0a484fd5b02ce74268eaa7e0c697b904f31d6c"}, - {file = "scikit_learn-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfeaf8be72117eb61a164ea6fc8afb6dfe08c6f90365bde2dc16456e4bc8e45f"}, - {file = "scikit_learn-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:fe0aa1a7029ed3e1dcbf4a5bc675aa3b1bc468d9012ecf6c6f081251ca47f590"}, - {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:065e9673e24e0dc5113e2dd2b4ca30c9d8aa2fa90f4c0597241c93b63130d233"}, - {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf036ea7ef66115e0d49655f16febfa547886deba20149555a41d28f56fd6d3c"}, - {file = "scikit_learn-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8b0670d4224a3c2d596fd572fb4fa673b2a0ccfb07152688ebd2ea0b8c61025c"}, - {file = "scikit_learn-1.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c710ff9f9936ba8a3b74a455ccf0dcf59b230caa1e9ba0223773c490cab1e51"}, - {file = "scikit_learn-1.2.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:2dd3ffd3950e3d6c0c0ef9033a9b9b32d910c61bd06cb8206303fb4514b88a49"}, - {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44b47a305190c28dd8dd73fc9445f802b6ea716669cfc22ab1eb97b335d238b1"}, - {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:953236889928d104c2ef14027539f5f2609a47ebf716b8cbe4437e85dce42744"}, - {file = "scikit_learn-1.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:7f69313884e8eb311460cc2f28676d5e400bd929841a2c8eb8742ae78ebf7c20"}, - {file = "scikit_learn-1.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8156db41e1c39c69aa2d8599ab7577af53e9e5e7a57b0504e116cc73c39138dd"}, - {file = "scikit_learn-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fe175ee1dab589d2e1033657c5b6bec92a8a3b69103e3dd361b58014729975c3"}, - {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d5312d9674bed14f73773d2acf15a3272639b981e60b72c9b190a0cffed5bad"}, - {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89"}, - {file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3"}, -] -scipy = [ - {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, - {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, - {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, - {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, - {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, - {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, - {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, -] -seaborn = [ - {file = "seaborn-0.12.2-py3-none-any.whl", hash = "sha256:ebf15355a4dba46037dfd65b7350f014ceb1f13c05e814eda2c9f5fd731afc08"}, - {file = "seaborn-0.12.2.tar.gz", hash = "sha256:374645f36509d0dcab895cba5b47daf0586f77bfe3b36c97c607db7da5be0139"}, -] -setuptools = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, -] -setuptools-scm = [ - {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, - {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, -] -shapely = [ - {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b06d031bc64149e340448fea25eee01360a58936c89985cf584134171e05863f"}, - {file = "shapely-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a6ac34c16f4d5d3c174c76c9d7614ec8fe735f8f82b6cc97a46b54f386a86bf"}, - {file = "shapely-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:865bc3d7cc0ea63189d11a0b1120d1307ed7a64720a8bfa5be2fde5fc6d0d33f"}, - {file = "shapely-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45b4833235b90bc87ee26c6537438fa77559d994d2d3be5190dd2e54d31b2820"}, - {file = "shapely-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce88ec79df55430e37178a191ad8df45cae90b0f6972d46d867bf6ebbb58cc4d"}, - {file = "shapely-2.0.1-cp310-cp310-win32.whl", hash = "sha256:01224899ff692a62929ef1a3f5fe389043e262698a708ab7569f43a99a48ae82"}, - {file = "shapely-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:da71de5bf552d83dcc21b78cc0020e86f8d0feea43e202110973987ffa781c21"}, - {file = "shapely-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:502e0a607f1dcc6dee0125aeee886379be5242c854500ea5fd2e7ac076b9ce6d"}, - {file = "shapely-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7d3bbeefd8a6a1a1017265d2d36f8ff2d79d0162d8c141aa0d37a87063525656"}, - {file = "shapely-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f470a130d6ddb05b810fc1776d918659407f8d025b7f56d2742a596b6dffa6c7"}, - {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4641325e065fd3e07d55677849c9ddfd0cf3ee98f96475126942e746d55b17c8"}, - {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90cfa4144ff189a3c3de62e2f3669283c98fb760cfa2e82ff70df40f11cadb39"}, - {file = "shapely-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70a18fc7d6418e5aea76ac55dce33f98e75bd413c6eb39cfed6a1ba36469d7d4"}, - {file = "shapely-2.0.1-cp311-cp311-win32.whl", hash = "sha256:09d6c7763b1bee0d0a2b84bb32a4c25c6359ad1ac582a62d8b211e89de986154"}, - {file = "shapely-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:d8f55f355be7821dade839df785a49dc9f16d1af363134d07eb11e9207e0b189"}, - {file = "shapely-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:83a8ec0ee0192b6e3feee9f6a499d1377e9c295af74d7f81ecba5a42a6b195b7"}, - {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a529218e72a3dbdc83676198e610485fdfa31178f4be5b519a8ae12ea688db14"}, - {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91575d97fd67391b85686573d758896ed2fc7476321c9d2e2b0c398b628b961c"}, - {file = "shapely-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8b0d834b11be97d5ab2b4dceada20ae8e07bcccbc0f55d71df6729965f406ad"}, - {file = "shapely-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:b4f0711cc83734c6fad94fc8d4ec30f3d52c1787b17d9dca261dc841d4731c64"}, - {file = "shapely-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:05c51a29336e604c084fb43ae5dbbfa2c0ef9bd6fedeae0a0d02c7b57a56ba46"}, - {file = "shapely-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b519cf3726ddb6c67f6a951d1bb1d29691111eaa67ea19ddca4d454fbe35949c"}, - {file = "shapely-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:193a398d81c97a62fc3634a1a33798a58fd1dcf4aead254d080b273efbb7e3ff"}, - {file = "shapely-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e55698e0ed95a70fe9ff9a23c763acfe0bf335b02df12142f74e4543095e9a9b"}, - {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32a748703e7bf6e92dfa3d2936b2fbfe76f8ce5f756e24f49ef72d17d26ad02"}, - {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a34a23d6266ca162499e4a22b79159dc0052f4973d16f16f990baa4d29e58b6"}, - {file = "shapely-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173d24e85e51510e658fb108513d5bc11e3fd2820db6b1bd0522266ddd11f51"}, - {file = "shapely-2.0.1-cp38-cp38-win32.whl", hash = "sha256:3cb256ae0c01b17f7bc68ee2ffdd45aebf42af8992484ea55c29a6151abe4386"}, - {file = "shapely-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c7eed1fb3008a8a4a56425334b7eb82651a51f9e9a9c2f72844a2fb394f38a6c"}, - {file = "shapely-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ac1dfc397475d1de485e76de0c3c91cc9d79bd39012a84bb0f5e8a199fc17bef"}, - {file = "shapely-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33403b8896e1d98aaa3a52110d828b18985d740cc9f34f198922018b1e0f8afe"}, - {file = "shapely-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2569a4b91caeef54dd5ae9091ae6f63526d8ca0b376b5bb9fd1a3195d047d7d4"}, - {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a70a614791ff65f5e283feed747e1cc3d9e6c6ba91556e640636bbb0a1e32a71"}, - {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43755d2c46b75a7b74ac6226d2cc9fa2a76c3263c5ae70c195c6fb4e7b08e79"}, - {file = "shapely-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad81f292fffbd568ae71828e6c387da7eb5384a79db9b4fde14dd9fdeffca9a"}, - {file = "shapely-2.0.1-cp39-cp39-win32.whl", hash = "sha256:b50c401b64883e61556a90b89948297f1714dbac29243d17ed9284a47e6dd731"}, - {file = "shapely-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bca57b683e3d94d0919e2f31e4d70fdfbb7059650ef1b431d9f4e045690edcd5"}, - {file = "shapely-2.0.1.tar.gz", hash = "sha256:66a6b1a3e72ece97fc85536a281476f9b7794de2e646ca8a4517e2e3c1446893"}, -] -simple-pytree = [ - {file = "simple_pytree-0.1.7-py3-none-any.whl", hash = "sha256:d84834955b153eeb22a944bdfeff7ce1a261e31ef347f0b1e07bb0eedbb3f0ea"}, - {file = "simple_pytree-0.1.7.tar.gz", hash = "sha256:037c5c492de191038c6625fb223da572ec321e829150f48c452e100d69bbffba"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -smmap = [ - {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, - {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, -] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -snuggs = [ - {file = "snuggs-1.4.7-py3-none-any.whl", hash = "sha256:988dde5d4db88e9d71c99457404773dabcc7a1c45971bfbe81900999942d9f07"}, - {file = "snuggs-1.4.7.tar.gz", hash = "sha256:501cf113fe3892e14e2fee76da5cd0606b7e149c411c271898e6259ebde2617b"}, -] -soupsieve = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, -] -stack-data = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, -] -tabulate = [ - {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, - {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, -] -tensorflow-probability = [ - {file = "tensorflow_probability-0.19.0-py2.py3-none-any.whl", hash = "sha256:ee70967fbd52b09e9c5ec148a9437c4cf3f9e9d689cdca400a1bc921f21cdcac"}, -] -tensorstore = [ - {file = "tensorstore-0.1.36-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:b1e3038778fd47ca351442276ff419bd3fb2e1e7c5c6c9956b341de81f869df1"}, - {file = "tensorstore-0.1.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25cc8e2c865b7193d68524752d14a39bce39e6797eeda47ce02062dc97c9b865"}, - {file = "tensorstore-0.1.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33ad5669e5f3ee705718978f5519d96b25ff43f607730ac473947b0bac4c66d9"}, - {file = "tensorstore-0.1.36-cp310-cp310-win_amd64.whl", hash = "sha256:e9bc007812ca44bc8156fb1a4511206f68763f350157befd0ce1e9c263af08d1"}, - {file = "tensorstore-0.1.36-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8a95aa206e8fb6b266744418dd859a19653e8e0d2e3d336f783a667ff1093678"}, - {file = "tensorstore-0.1.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90688379adbacb376ea8071e96c5a492db06beb45244a593f706525debeaf00f"}, - {file = "tensorstore-0.1.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b2b3b828e4af23296dbe88c2c66d57bcc40d92c7437687347693c73095f11d"}, - {file = "tensorstore-0.1.36-cp311-cp311-win_amd64.whl", hash = "sha256:296156ad263035b24273895ff222373dd58f0277c5cab6dc30b5d0d8a9abf3fb"}, - {file = "tensorstore-0.1.36-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:2461a028fc6542b6342aa6a25119cdbbffe6194da359ecdd6e585b04d14fd269"}, - {file = "tensorstore-0.1.36-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:de48cd37f266a9f1a1b10bba39d47f58e6d7fe04bb2a01329516c2daf0626c71"}, - {file = "tensorstore-0.1.36-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c351605e18298541aef6662edc9acb6f567ab8b4e548e4d4788e075aceec7d5d"}, - {file = "tensorstore-0.1.36-cp38-cp38-win_amd64.whl", hash = "sha256:798c6b66019647231fead25b39e95caa08fa270d22226117d6738b3f2d68372f"}, - {file = "tensorstore-0.1.36-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:634e6fae8019c741199d512ce34077b24e84791e5f6b8e46a6e76aa5aef97c2f"}, - {file = "tensorstore-0.1.36-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96aa9e50f492ed848e73d5a24d187ec679ec4b4f5ebe360e1938c46ccc6a3ff6"}, - {file = "tensorstore-0.1.36-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50b27919cde623e3918fe6ba054f41e2da5d7dbf7817d46d43131b50bcc9df4"}, - {file = "tensorstore-0.1.36-cp39-cp39-win_amd64.whl", hash = "sha256:acc46ed5e59faee6823ad39b807daeb40447fac2068163b7c558cc3a0d7a0b71"}, - {file = "tensorstore-0.1.36.tar.gz", hash = "sha256:733b629a65f1d47cc1b19fb1df2de75111ae228081655746d335ed3c21902bbd"}, -] -threadpoolctl = [ - {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, - {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, -] -tinycss2 = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -tomlkit = [ - {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, - {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, -] -toolz = [ - {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, - {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, -] -tornado = [ - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:db181eb3df8738613ff0a26f49e1b394aade05034b01200a63e9662f347d4415"}, - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b4e7b956f9b5e6f9feb643ea04f07e7c6b49301e03e0023eedb01fa8cf52f579"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661aa8bc0e9d83d757cd95b6f6d1ece8ca9fd1ccdd34db2de381e25bf818233"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81c17e0cc396908a5e25dc8e9c5e4936e6dfd544c9290be48bd054c79bcad51e"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27a1cfa9997923f80bdd962b3aab048ac486ad8cfb2f237964f8ab7f7eb824b"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d7117f3c7ba5d05813b17a1f04efc8e108a1b811ccfddd9134cc68553c414864"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:ffdce65a281fd708da5a9def3bfb8f364766847fa7ed806821a69094c9629e8a"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:90f569a35a8ec19bde53aa596952071f445da678ec8596af763b9b9ce07605e6"}, - {file = "tornado-6.3.1-cp38-abi3-win32.whl", hash = "sha256:3455133b9ff262fd0a75630af0a8ee13564f25fb4fd3d9ce239b8a7d3d027bf8"}, - {file = "tornado-6.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:1285f0691143f7ab97150831455d4db17a267b59649f7bd9700282cba3d5e771"}, - {file = "tornado-6.3.1.tar.gz", hash = "sha256:5e2f49ad371595957c50e42dd7e5c14d64a6843a3cf27352b69c706d1b5918af"}, -] -tqdm = [ - {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, - {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, -] -traitlets = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, -] -typeguard = [ - {file = "typeguard-3.0.2-py3-none-any.whl", hash = "sha256:bbe993854385284ab42fd5bd3bee6f6556577ce8b50696d6cb956d704f286c8e"}, - {file = "typeguard-3.0.2.tar.gz", hash = "sha256:fee5297fdb28f8e9efcb8142b5ee219e02375509cd77ea9d270b5af826358d5a"}, -] -typing-extensions = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, -] -uc-micro-py = [ - {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, - {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, -] -urllib3 = [ - {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, - {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, -] -validators = [ - {file = "validators-0.20.0.tar.gz", hash = "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"}, -] -virtualenv = [ - {file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, - {file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, -] -watchdog = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, -] -watermark = [ - {file = "watermark-2.3.1-py2.py3-none-any.whl", hash = "sha256:8e2681e512660e50d2aa460fd7d40d8ed2862735ae5087fc0ec7752fb10ee29c"}, - {file = "watermark-2.3.1.tar.gz", hash = "sha256:0a69eb017f4f96e909739f25ce1a3bd0729c65d8cf4294ea07d609322360019a"}, -] -wcwidth = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, -] -webencodings = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] -wheel = [ - {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"}, - {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"}, -] -widgetsnbextension = [ - {file = "widgetsnbextension-4.0.7-py3-none-any.whl", hash = "sha256:be3228a73bbab189a16be2d4a3cd89ecbd4e31948bfdc64edac17dcdee3cd99c"}, - {file = "widgetsnbextension-4.0.7.tar.gz", hash = "sha256:ea67c17a7cd4ae358f8f46c3b304c40698bc0423732e3f273321ee141232c8be"}, -] -wrapt = [ +files = [ {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, @@ -5363,15 +5652,68 @@ wrapt = [ {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] -xarray = [ - {file = "xarray-2023.1.0-py3-none-any.whl", hash = "sha256:7e530b1deafdd43e5c2b577d0944e6b528fbe88045fd849e49a8d11871ecd522"}, - {file = "xarray-2023.1.0.tar.gz", hash = "sha256:7bee552751ff1b29dab8b7715726e5ecb56691ac54593cf4881dff41978ce0cd"}, + +[[package]] +name = "xarray" +version = "2023.8.0" +description = "N-D labeled arrays and datasets in Python" +category = "dev" +optional = false +python-versions = ">=3.9" +files = [ + {file = "xarray-2023.8.0-py3-none-any.whl", hash = "sha256:eb42b56aea2c7d5db2a7d0c33fb005b78eb5c4421eb747f2ced138c70b5c204e"}, + {file = "xarray-2023.8.0.tar.gz", hash = "sha256:825c6d64202a731a4e49321edd1e9dfabf4be06802f1b8c8a3c00a3ebfc8cedf"}, ] -xdoctest = [ + +[package.dependencies] +numpy = ">=1.21" +packaging = ">=21.3" +pandas = ">=1.4" + +[package.extras] +accel = ["bottleneck", "flox", "numbagg", "scipy"] +complete = ["bottleneck", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "matplotlib", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "scipy", "seaborn", "zarr"] +docs = ["bottleneck", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "ipykernel", "ipython", "jupyter-client", "matplotlib", "nbsphinx", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "scanpydoc", "scipy", "seaborn", "sphinx-autosummary-accessors", "sphinx-rtd-theme", "zarr"] +io = ["cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "scipy", "zarr"] +parallel = ["dask[complete]"] +viz = ["matplotlib", "nc-time-axis", "seaborn"] + +[[package]] +name = "xdoctest" +version = "1.1.1" +description = "A rewrite of the builtin doctest module" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ {file = "xdoctest-1.1.1-py3-none-any.whl", hash = "sha256:d59d4ed91cb92e4430ef0ad1b134a2bef02adff7d2fb9c9f057547bee44081a2"}, {file = "xdoctest-1.1.1.tar.gz", hash = "sha256:2eac8131bdcdf2781b4e5a62d6de87f044b730cc8db8af142a51bb29c245e779"}, ] -yarl = [ + +[package.dependencies] +six = "*" + +[package.extras] +all = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "codecov", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "pytest", "pytest", "pytest", "pytest-cov", "six", "tomli", "typing"] +all-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "codecov (==2.0.15)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "six (==1.11.0)", "tomli (==0.2.0)", "typing (==3.7.4)"] +colors = ["Pygments", "Pygments", "colorama"] +jupyter = ["IPython", "IPython", "attrs", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert"] +optional = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "tomli"] +optional-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "tomli (==0.2.0)"] +runtime-strict = ["six (==1.11.0)"] +tests = ["codecov", "pytest", "pytest", "pytest", "pytest-cov", "typing"] +tests-binary = ["cmake", "cmake", "ninja", "ninja", "pybind11", "pybind11", "scikit-build", "scikit-build"] +tests-binary-strict = ["cmake (==3.21.2)", "cmake (==3.25.0)", "ninja (==1.10.2)", "ninja (==1.11.1)", "pybind11 (==2.10.3)", "pybind11 (==2.7.1)", "scikit-build (==0.11.1)", "scikit-build (==0.16.1)"] +tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "typing (==3.7.4)"] + +[[package]] +name = "yarl" +version = "1.9.2" +description = "Yet another URL library" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82"}, {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8"}, {file = "yarl-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9"}, @@ -5447,7 +5789,28 @@ yarl = [ {file = "yarl-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18"}, {file = "yarl-1.9.2.tar.gz", hash = "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571"}, ] -zipp = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zipp" +version = "3.16.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, + {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, ] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.10,<3.12" +content-hash = "9b0aa2fdb17f57a3836ebe54d26eb4b1f5aa376a50688db810b3498a514b228a" diff --git a/tests/test_gaussian_distribution.py b/tests/test_gaussian_distribution.py index 351ca7e31..01114bb9e 100644 --- a/tests/test_gaussian_distribution.py +++ b/tests/test_gaussian_distribution.py @@ -169,7 +169,7 @@ def test_masked_log_prob(n): _L = jnp.linalg.cholesky(covariance) # noqa: F841 # check that masked log_prob is equal to tfp log_prob with missing values removed - dist = GaussianDistribution(loc=mean, scale=DenseLinearOperator(covariance)) + dist = GaussianDistribution(loc=mean, scale=Dense(covariance)) tfp_dist = MultivariateNormalFullCovariance( loc=mean[~mask], covariance_matrix=covariance[~mask][:, ~mask] ) From abc9f88bb5ee7ad0072bf7bf47cff6111359969b Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Sat, 26 Aug 2023 20:57:12 +0100 Subject: [PATCH 60/76] Bump tests to Python>=3.10 --- .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 e27b12c52..b3d747e90 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: matrix: # Select the Python versions to test against os: ["ubuntu-latest", "macos-latest"] - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11"] fail-fast: true steps: - name: Check out the code From 91854719274781ffbff6bfd3405fa500f56661c5 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Tue, 29 Aug 2023 13:02:15 +0100 Subject: [PATCH 61/76] Drop cola's special plum, and use single dispatch for citations. --- gpjax/citation.py | 44 +++++++++++++++++++++++--------------------- poetry.lock | 2 +- pyproject.toml | 1 - tests/conftest.py | 8 ++++---- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/gpjax/citation.py b/gpjax/citation.py index 74a7a7391..52fce6911 100644 --- a/gpjax/citation.py +++ b/gpjax/citation.py @@ -2,13 +2,13 @@ dataclass, fields, ) +from functools import singledispatch from beartype.typing import ( Dict, Union, ) from jaxlib.xla_extension import PjitFunction -from plum import dispatch from gpjax.kernels import ( RFF, @@ -26,8 +26,6 @@ NonConjugateMLL, ) -MaternKernels = Union[Matern12, Matern32, Matern52] -MLLs = Union[ConjugateMLL, NonConjugateMLL, LogPosteriorDensity] CitationType = Union[str, Dict[str, str]] @@ -89,24 +87,26 @@ class BookCitation(AbstractCitation): #################### # Default citation #################### -@dispatch -def cite(tree) -> NullCitation: +@singledispatch +def cite(tree) -> AbstractCitation: return NullCitation() #################### # Default citation #################### -@dispatch -def cite(tree: PjitFunction) -> JittedFnCitation: +@cite.register(PjitFunction) +def _(tree): return JittedFnCitation() #################### # Kernel citations #################### -@dispatch -def cite(tree: MaternKernels) -> PhDThesisCitation: +@cite.register(Matern12) +@cite.register(Matern32) +@cite.register(Matern52) +def _(tree) -> PhDThesisCitation: citation = PhDThesisCitation( citation_key="matern1960SpatialV", authors="Bertil Matérn", @@ -121,8 +121,8 @@ def cite(tree: MaternKernels) -> PhDThesisCitation: return citation -@dispatch -def cite(tree: ArcCosine) -> PaperCitation: +@cite.register(ArcCosine) +def _(_) -> PaperCitation: return PaperCitation( citation_key="cho2009kernel", authors="Cho, Youngmin and Saul, Lawrence", @@ -132,8 +132,8 @@ def cite(tree: ArcCosine) -> PaperCitation: ) -@dispatch -def cite(tree: GraphKernel) -> PaperCitation: +@cite.register(GraphKernel) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="borovitskiy2021matern", title="Matérn Gaussian Processes on Graphs", @@ -146,8 +146,8 @@ def cite(tree: GraphKernel) -> PaperCitation: ) -@dispatch -def cite(tree: RFF) -> PaperCitation: +@cite.register(RFF) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="rahimi2007random", authors="Rahimi, Ali and Recht, Benjamin", @@ -161,8 +161,10 @@ def cite(tree: RFF) -> PaperCitation: #################### # Objective citations #################### -@dispatch -def cite(tree: MLLs) -> BookCitation: +@cite.register(ConjugateMLL) +@cite.register(NonConjugateMLL) +@cite.register(LogPosteriorDensity) +def _(tree) -> BookCitation: return BookCitation( citation_key="rasmussen2006gaussian", title="Gaussian Processes for Machine Learning", @@ -173,8 +175,8 @@ def cite(tree: MLLs) -> BookCitation: ) -@dispatch -def cite(tree: CollapsedELBO) -> PaperCitation: +@cite.register(CollapsedELBO) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="titsias2009variational", title="Variational learning of inducing variables in sparse Gaussian processes", @@ -184,8 +186,8 @@ def cite(tree: CollapsedELBO) -> PaperCitation: ) -@dispatch -def cite(tree: ELBO) -> PaperCitation: +@cite.register(ELBO) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="hensman2013gaussian", title="Gaussian Processes for Big Data", diff --git a/poetry.lock b/poetry.lock index c8c8daf90..b386e35c6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5813,4 +5813,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "9b0aa2fdb17f57a3836ebe54d26eb4b1f5aa376a50688db810b3498a514b228a" +content-hash = "95048d017009d7fafa176580db39b5b348e1dded982777edc6771ceb8e0c6135" diff --git a/pyproject.toml b/pyproject.toml index 80f057f84..fe27586de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ jax = ">=0.4.10" jaxlib = ">=0.4.10" orbax-checkpoint = ">=0.2.3" cola-ml = "^0.0.1" -cola-plum-dispatch = "^0.1.1" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" diff --git a/tests/conftest.py b/tests/conftest.py index e12a1f72d..451074f1f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ -from jaxtyping import install_import_hook +# from jaxtyping import install_import_hook -# import gpjax within import hook to apply beartype everywhere, before running tests -with install_import_hook("gpjax", "beartype.beartype"): - import gpjax # noqa: F401 +# # import gpjax within import hook to apply beartype everywhere, before running tests +# with install_import_hook("gpjax", "beartype.beartype"): +# import gpjax # noqa: F401 From 07d94d4ac904a8b748aa68ca0f7d6106f1888075 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Tue, 29 Aug 2023 13:18:22 +0100 Subject: [PATCH 62/76] Test Gaussian cov is PSD, bump workflows to python 3.10 --- .github/workflows/build_docs.yml | 2 +- .github/workflows/integration.yml | 2 +- .github/workflows/test_docs.yml | 2 +- gpjax/lower_cholesky.py | 2 +- tests/test_gaussian_distribution.py | 8 ++++++++ tests/test_kernels/test_computation.py | 3 ++- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index c2a4c5887..539989456 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest"] - python-version: ["3.8"] + python-version: ["3.10"] steps: # Grap the latest commit from the branch diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 214243ba8..b6d07cc2b 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -13,7 +13,7 @@ jobs: matrix: # Select the Python versions to test against os: ["ubuntu-latest", "macos-latest"] - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11"] fail-fast: true steps: - name: Check out the code diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml index 55dc208af..bbf7f5b4c 100644 --- a/.github/workflows/test_docs.yml +++ b/.github/workflows/test_docs.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest"] - python-version: ["3.8"] + python-version: ["3.10"] steps: # Grap the latest commit from the branch diff --git a/gpjax/lower_cholesky.py b/gpjax/lower_cholesky.py index a47eaafd3..69286ead0 100644 --- a/gpjax/lower_cholesky.py +++ b/gpjax/lower_cholesky.py @@ -16,7 +16,7 @@ import cola import jax.numpy as jnp -# TODO: Add lower_cholesky for other linear operators. +# TODO: Once this functionality is supported in CoLA, remove this. @cola.dispatch diff --git a/tests/test_gaussian_distribution.py b/tests/test_gaussian_distribution.py index 01114bb9e..a59774563 100644 --- a/tests/test_gaussian_distribution.py +++ b/tests/test_gaussian_distribution.py @@ -60,6 +60,9 @@ def test_array_arguments(n: int) -> None: assert approx_equal(dist.stddev(), jnp.sqrt(covariance.diagonal())) assert approx_equal(dist.covariance(), covariance) + assert isinstance(dist.scale, Dense) + assert cola.PSD in dist.scale.annotations + y = jr.uniform(_key, shape=(n,)) tfp_dist = MultivariateNormalFullCovariance(loc=mean, covariance_matrix=covariance) @@ -74,9 +77,14 @@ def test_diag_linear_operator(n: int) -> None: mean = jr.uniform(key_mean, shape=(n,)) diag = jr.uniform(key_diag, shape=(n,)) + # We purosely forget to add a PSD annotation to the diagonal matrix. dist_diag = GaussianDistribution(loc=mean, scale=Diagonal(diag**2)) tfp_dist = MultivariateNormalDiag(loc=mean, scale_diag=diag) + # We check that the PSD annotation is added automatically. + assert isinstance(dist_diag.scale, Diagonal) + assert cola.PSD in dist_diag.scale.annotations + assert approx_equal(dist_diag.mean(), tfp_dist.mean()) assert approx_equal(dist_diag.mode(), tfp_dist.mode()) assert approx_equal(dist_diag.entropy(), tfp_dist.entropy()) diff --git a/tests/test_kernels/test_computation.py b/tests/test_kernels/test_computation.py index 635e730fa..888073941 100644 --- a/tests/test_kernels/test_computation.py +++ b/tests/test_kernels/test_computation.py @@ -9,6 +9,7 @@ from gpjax.kernels.computations import ( ConstantDiagonalKernelComputation, DiagonalKernelComputation, + BasisFunctionComputation, ) from gpjax.kernels.nonstationary import ( Linear, @@ -77,4 +78,4 @@ def test_change_computation(kernel): assert jnp.allclose(constant_entries, constant_entries[0]) # All the off diagonal entries should be zero - assert jnp.allclose(constant_diagonal_matrix - jnp.diag(constant_entries), 0.0) + assert jnp.allclose(constant_diagonal_matrix - jnp.diag(constant_entries), 0.0) \ No newline at end of file From 9568a974fee216e63d8ce6cc19f802e9c81b8afc Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 30 Aug 2023 18:57:55 +0100 Subject: [PATCH 63/76] Add Kronecker and BlockDiag to lower_cholesky. --- gpjax/lower_cholesky.py | 17 ++++++++ tests/test_lower_cholesky.py | 80 +++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/gpjax/lower_cholesky.py b/gpjax/lower_cholesky.py index 69286ead0..274dbee26 100644 --- a/gpjax/lower_cholesky.py +++ b/gpjax/lower_cholesky.py @@ -30,6 +30,11 @@ def lower_cholesky(A: cola.ops.LinearOperator): # noqa: F811 cola.ops.LinearOperator: The lower Cholesky factor of A. """ + if cola.PSD not in A.annotations: + raise ValueError( + "Expected LinearOperator to be PSD, did you forget to use cola.PSD?" + ) + return cola.ops.Triangular(jnp.linalg.cholesky(A.to_dense()), lower=True) @@ -41,3 +46,15 @@ def _(A: cola.ops.Diagonal): # noqa: F811 @lower_cholesky.dispatch def _(A: cola.ops.Identity): # noqa: F811 return A + + +@lower_cholesky.dispatch +def _(A: cola.ops.Kronecker): # noqa: F811 + return cola.ops.Kronecker(*[lower_cholesky(Ai) for Ai in A.Ms]) + + +@lower_cholesky.dispatch +def _(A: cola.ops.BlockDiag): # noqa: F811 + return cola.ops.BlockDiag( + *[lower_cholesky(Ai) for Ai in A.Ms], multiplicities=A.multiplicities + ) diff --git a/tests/test_lower_cholesky.py b/tests/test_lower_cholesky.py index e00c1ea23..d8487c522 100644 --- a/tests/test_lower_cholesky.py +++ b/tests/test_lower_cholesky.py @@ -1,18 +1,30 @@ +import cola from cola.ops import ( + BlockDiag, Dense, Diagonal, I_like, Identity, + Kronecker, Triangular, ) import jax.numpy as jnp +import jax.scipy as jsp +import pytest from gpjax.lower_cholesky import lower_cholesky def test_dense() -> None: array = jnp.array([[3.0, 1.0], [1.0, 3.0]]) - A = Dense(array) + + # Test that we get an error if we don't use cola.PSD! + with pytest.raises(ValueError): + A = Dense(array) + lower_cholesky(A) + + # Now we annoate with cola.PSD and test for the correct output. + A = cola.PSD(Dense(array)) L = lower_cholesky(A) assert isinstance(L, Triangular) @@ -21,7 +33,7 @@ def test_dense() -> None: def test_diagonal() -> None: array = jnp.array([1.0, 2.0]) - A = Diagonal(array) + A = cola.PSD(Diagonal(array)) L = lower_cholesky(A) assert isinstance(L, Diagonal) @@ -33,3 +45,67 @@ def test_identity() -> None: L = lower_cholesky(A) assert isinstance(L, Identity) assert jnp.allclose(L.to_dense(), jnp.eye(2)) + + +def test_kronecker() -> None: + array_a = jnp.array([[3.0, 1.0], [1.0, 3.0]]) + array_b = jnp.array([[2.0, 0.0], [0.0, 2.0]]) + + # Create LinearOperators. + A = Dense(array_a) + B = Dense(array_b) + + # Annotate with cola.PSD. + A = cola.PSD(A) + B = cola.PSD(B) + + K = Kronecker(A, B) + + # Cholesky decomposition. + L = lower_cholesky(K) + + # Check types. + assert isinstance(L, Kronecker) + assert isinstance(L.Ms[0], Triangular) + assert isinstance(L.Ms[1], Triangular) + + # Check values. + assert jnp.allclose(L.Ms[0].to_dense(), jnp.linalg.cholesky(array_a)) + assert jnp.allclose(L.Ms[1].to_dense(), jnp.linalg.cholesky(array_b)) + assert jnp.allclose( + L.to_dense(), + jnp.kron(jnp.linalg.cholesky(array_a), jnp.linalg.cholesky(array_b)), + ) + + +def test_block_diag() -> None: + array_a = jnp.array([[3.0, 1.0], [1.0, 3.0]]) + array_b = jnp.array([[2.0, 0.0], [0.0, 2.0]]) + + # Create LinearOperators. + A = Dense(array_a) + B = Dense(array_b) + + # Annotate with cola.PSD. + A = cola.PSD(A) + B = cola.PSD(B) + + B = BlockDiag(A, B, multiplicities=[2, 3]) + + # Cholesky decomposition. + L = lower_cholesky(B) + + # Check types. + assert isinstance(L, BlockDiag) + assert isinstance(L.Ms[0], Triangular) + assert isinstance(L.Ms[1], Triangular) + + # Check values. + assert jnp.allclose(L.Ms[0].to_dense(), jnp.linalg.cholesky(array_a)) + assert jnp.allclose(L.Ms[1].to_dense(), jnp.linalg.cholesky(array_b)) + + # Check multiplicities. + assert L.multiplicities == [2, 3] + + # Check dense. + assert jnp.allclose(jnp.linalg.cholesky(B.to_dense()), L.to_dense()) From 4c8aa650c2b71ab265aefaf2a52b15e5a2ec7253 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 14:14:52 +0100 Subject: [PATCH 64/76] Remove imports --- tests/test_kernels/test_computation.py | 3 +-- tests/test_lower_cholesky.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_kernels/test_computation.py b/tests/test_kernels/test_computation.py index 888073941..635e730fa 100644 --- a/tests/test_kernels/test_computation.py +++ b/tests/test_kernels/test_computation.py @@ -9,7 +9,6 @@ from gpjax.kernels.computations import ( ConstantDiagonalKernelComputation, DiagonalKernelComputation, - BasisFunctionComputation, ) from gpjax.kernels.nonstationary import ( Linear, @@ -78,4 +77,4 @@ def test_change_computation(kernel): assert jnp.allclose(constant_entries, constant_entries[0]) # All the off diagonal entries should be zero - assert jnp.allclose(constant_diagonal_matrix - jnp.diag(constant_entries), 0.0) \ No newline at end of file + assert jnp.allclose(constant_diagonal_matrix - jnp.diag(constant_entries), 0.0) diff --git a/tests/test_lower_cholesky.py b/tests/test_lower_cholesky.py index d8487c522..dff31cfbc 100644 --- a/tests/test_lower_cholesky.py +++ b/tests/test_lower_cholesky.py @@ -9,7 +9,6 @@ Triangular, ) import jax.numpy as jnp -import jax.scipy as jsp import pytest from gpjax.lower_cholesky import lower_cholesky From 62406462c3a2a843cf71332acde9f4e2c2c05603 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 14:42:17 +0100 Subject: [PATCH 65/76] Fix notebook and ignore citations in interrogate. --- docs/examples/classification.py | 6 ++++-- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/examples/classification.py b/docs/examples/classification.py index 59775abe0..005d7f743 100644 --- a/docs/examples/classification.py +++ b/docs/examples/classification.py @@ -207,13 +207,15 @@ # datapoints below. # %% +from gpjax.lower_cholesky import lower_cholesky + gram, cross_covariance = (kernel.gram, kernel.cross_covariance) jitter = 1e-6 # Compute (latent) function value map estimates at training points: Kxx = opt_posterior.prior.kernel.gram(x) Kxx += identity_matrix(D.n) * jitter -Lx = Kxx.to_root() +Lx = lower_cholesky(Kxx) f_hat = Lx @ opt_posterior.latent # Negative Hessian, H = -∇²p_tilde(y|f): @@ -250,7 +252,7 @@ def construct_laplace(test_inputs: Float[Array, "N D"]) -> tfd.MultivariateNorma Kxt = opt_posterior.prior.kernel.cross_covariance(x, test_inputs) Kxx = opt_posterior.prior.kernel.gram(x) Kxx += identity_matrix(D.n) * jitter - Lx = Kxx.to_root() + Lx = lower_cholesky(Kxx) # Lx⁻¹ Kxt Lx_inv_Ktx = Lx.solve(Kxt) diff --git a/pyproject.toml b/pyproject.toml index fe27586de..6794e2091 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -208,7 +208,7 @@ ignore-words-list = "fro" # Frobenius ignore-init-method = true ignore-init-module = true fail-under = 64 -exclude = ["setup.py", "docs", "tests"] +exclude = ["setup.py", "docs", "tests", "gpjax/__init__.py", "gpjax/citation.py"] verbose = 2 quiet = false color = true From f3b91ad2eb51b706d0ea17dd6bf0a63fb68636c8 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 15:10:24 +0100 Subject: [PATCH 66/76] Update classification.py --- docs/examples/classification.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/examples/classification.py b/docs/examples/classification.py index 005d7f743..22c7107d5 100644 --- a/docs/examples/classification.py +++ b/docs/examples/classification.py @@ -207,6 +207,7 @@ # datapoints below. # %% +import cola from gpjax.lower_cholesky import lower_cholesky gram, cross_covariance = (kernel.gram, kernel.cross_covariance) @@ -215,6 +216,7 @@ # Compute (latent) function value map estimates at training points: Kxx = opt_posterior.prior.kernel.gram(x) Kxx += identity_matrix(D.n) * jitter +Kxx = cola.PSD(Kxx) Lx = lower_cholesky(Kxx) f_hat = Lx @ opt_posterior.latent @@ -252,6 +254,7 @@ def construct_laplace(test_inputs: Float[Array, "N D"]) -> tfd.MultivariateNorma Kxt = opt_posterior.prior.kernel.cross_covariance(x, test_inputs) Kxx = opt_posterior.prior.kernel.gram(x) Kxx += identity_matrix(D.n) * jitter + Kxx = cola.PSD(Kxx) Lx = lower_cholesky(Kxx) # Lx⁻¹ Kxt From 754d19cea28ca0c3b1b04ec14202395501f926a8 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 16:41:58 +0100 Subject: [PATCH 67/76] Fix sqrt to lower cholesky. --- docs/examples/classification.ipynb | 779 +++++++++++++++++++++++++++++ docs/examples/classification.py | 8 +- gpjax/objectives.py | 5 +- 3 files changed, 784 insertions(+), 8 deletions(-) create mode 100644 docs/examples/classification.ipynb diff --git a/docs/examples/classification.ipynb b/docs/examples/classification.ipynb new file mode 100644 index 000000000..90e264f1c --- /dev/null +++ b/docs/examples/classification.ipynb @@ -0,0 +1,779 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f78d3318", + "metadata": {}, + "source": [ + "# Classification\n", + "\n", + "In this notebook we demonstrate how to perform inference for Gaussian process models\n", + "with non-Gaussian likelihoods via maximum a posteriori (MAP) and Markov chain Monte\n", + "Carlo (MCMC). We focus on a classification task here and use\n", + "[BlackJax](https://github.com/blackjax-devs/blackjax/) for sampling." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1610bd93", + "metadata": {}, + "outputs": [], + "source": [ + "# Enable Float64 for more stable matrix inversions.\n", + "from jax.config import config\n", + "\n", + "config.update(\"jax_enable_x64\", True)\n", + "\n", + "from time import time\n", + "import blackjax\n", + "import jax\n", + "import jax.numpy as jnp\n", + "import jax.random as jr\n", + "import jax.scipy as jsp\n", + "import jax.tree_util as jtu\n", + "from jaxtyping import (\n", + " Array,\n", + " Float,\n", + " install_import_hook,\n", + ")\n", + "import matplotlib.pyplot as plt\n", + "import optax as ox\n", + "import tensorflow_probability.substrates.jax as tfp\n", + "from tqdm import trange\n", + "\n", + "with install_import_hook(\"gpjax\", \"beartype.beartype\"):\n", + " import gpjax as gpx\n", + "\n", + "tfd = tfp.distributions\n", + "identity_matrix = jnp.eye\n", + "key = jr.PRNGKey(123)\n", + "plt.style.use(\n", + " \"https://raw.githubusercontent.com/JaxGaussianProcesses/GPJax/main/docs/examples/gpjax.mplstyle\"\n", + ")\n", + "cols = plt.rcParams[\"axes.prop_cycle\"].by_key()[\"color\"]" + ] + }, + { + "cell_type": "markdown", + "id": "a96a36dc", + "metadata": {}, + "source": [ + "## Dataset\n", + "\n", + "With the necessary modules imported, we simulate a dataset\n", + "$\\mathcal{D} = (\\boldsymbol{x}, \\boldsymbol{y}) = \\{(x_i, y_i)\\}_{i=1}^{100}$ with inputs\n", + "$\\boldsymbol{x}$ sampled uniformly on $(-1., 1)$ and corresponding binary outputs\n", + "\n", + "$$\\boldsymbol{y} = 0.5 * \\text{sign}(\\cos(2 * + \\boldsymbol{\\epsilon})) + 0.5, \\quad \\boldsymbol{\\epsilon} \\sim \\mathcal{N} \\left(\\textbf{0}, \\textbf{I} * (0.05)^{2} \\right).$$\n", + "\n", + "We store our data $\\mathcal{D}$ as a GPJax `Dataset` and create test inputs for\n", + "later." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9abfffa3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "key, subkey = jr.split(key)\n", + "x = jr.uniform(key, shape=(100, 1), minval=-1.0, maxval=1.0)\n", + "y = 0.5 * jnp.sign(jnp.cos(3 * x + jr.normal(subkey, shape=x.shape) * 0.05)) + 0.5\n", + "\n", + "D = gpx.Dataset(X=x, y=y)\n", + "\n", + "xtest = jnp.linspace(-1.0, 1.0, 500).reshape(-1, 1)\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.scatter(x, y)" + ] + }, + { + "cell_type": "markdown", + "id": "9db6c8d8", + "metadata": {}, + "source": [ + "## MAP inference\n", + "\n", + "We begin by defining a Gaussian process prior with a radial basis function (RBF)\n", + "kernel, chosen for the purpose of exposition. Since our observations are binary, we\n", + "choose a Bernoulli likelihood with a probit link function." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1ac7588f", + "metadata": {}, + "outputs": [], + "source": [ + "kernel = gpx.RBF()\n", + "meanf = gpx.Constant()\n", + "prior = gpx.Prior(mean_function=meanf, kernel=kernel)\n", + "likelihood = gpx.Bernoulli(num_datapoints=D.n)" + ] + }, + { + "cell_type": "markdown", + "id": "8240564e", + "metadata": {}, + "source": [ + "We construct the posterior through the product of our prior and likelihood." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "335b6ead", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "posterior = prior * likelihood\n", + "print(type(posterior))" + ] + }, + { + "cell_type": "markdown", + "id": "d5553eee", + "metadata": {}, + "source": [ + "Whilst the latent function is Gaussian, the posterior distribution is non-Gaussian\n", + "since our generative model first samples the latent GP and propagates these samples\n", + "through the likelihood function's inverse link function. This step prevents us from\n", + "being able to analytically integrate the latent function's values out of our\n", + "posterior, and we must instead adopt alternative inference techniques. We begin with\n", + "maximum a posteriori (MAP) estimation, a fast inference procedure to obtain point\n", + "estimates for the latent function and the kernel's hyperparameters by maximising the\n", + "marginal log-likelihood." + ] + }, + { + "cell_type": "markdown", + "id": "91485478", + "metadata": {}, + "source": [ + "We can obtain a MAP estimate by optimising the log-posterior density with\n", + "Optax's optimisers." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "0192a42a", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0e78f1d26f0a48c79e5db78bfa48948d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1000 [00:00" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "map_latent_dist = opt_posterior.predict(xtest, train_data=D)\n", + "predictive_dist = opt_posterior.likelihood(map_latent_dist)\n", + "\n", + "predictive_mean = predictive_dist.mean()\n", + "predictive_std = predictive_dist.stddev()\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.scatter(x, y, label=\"Observations\", color=cols[0])\n", + "ax.plot(xtest, predictive_mean, label=\"Predictive mean\", color=cols[1])\n", + "ax.fill_between(\n", + " xtest.squeeze(),\n", + " predictive_mean - predictive_std,\n", + " predictive_mean + predictive_std,\n", + " alpha=0.2,\n", + " color=cols[1],\n", + " label=\"One sigma\",\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean - predictive_std,\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean + predictive_std,\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "\n", + "ax.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "e78427fe", + "metadata": {}, + "source": [ + "Here we projected the map estimates $\\hat{\\boldsymbol{f}}$ for the function values\n", + "$\\boldsymbol{f}$ at the data points $\\boldsymbol{x}$ to get predictions over the\n", + "whole domain,\n", + "\n", + "\\begin{align}\n", + "p(f(\\cdot)| \\mathcal{D}) \\approx q_{map}(f(\\cdot)) := \\int p(f(\\cdot)| \\boldsymbol{f}) \\delta(\\boldsymbol{f} - \\hat{\\boldsymbol{f}}) d \\boldsymbol{f} = \\mathcal{N}(\\mathbf{K}_{\\boldsymbol{(\\cdot)x}} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} \\hat{\\boldsymbol{f}}, \\mathbf{K}_{\\boldsymbol{(\\cdot, \\cdot)}} - \\mathbf{K}_{\\boldsymbol{(\\cdot)\\boldsymbol{x}}} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} \\mathbf{K}_{\\boldsymbol{\\boldsymbol{x}(\\cdot)}}).\n", + "\\end{align}" + ] + }, + { + "cell_type": "markdown", + "id": "7cf8263e", + "metadata": {}, + "source": [ + "However, as a point estimate, MAP estimation is severely limited for uncertainty\n", + "quantification, providing only a single piece of information about the posterior." + ] + }, + { + "cell_type": "markdown", + "id": "e0703339", + "metadata": {}, + "source": [ + "## Laplace approximation\n", + "The Laplace approximation improves uncertainty quantification by incorporating\n", + "curvature induced by the marginal log-likelihood's Hessian to construct an\n", + "approximate Gaussian distribution centered on the MAP estimate. Writing\n", + "$\\tilde{p}(\\boldsymbol{f}|\\mathcal{D}) = p(\\boldsymbol{y}|\\boldsymbol{f}) p(\\boldsymbol{f})$\n", + "as the unormalised posterior for function values $\\boldsymbol{f}$ at the datapoints\n", + "$\\boldsymbol{x}$, we can expand the log of this about the posterior mode\n", + "$\\hat{\\boldsymbol{f}}$ via a Taylor expansion. This gives:\n", + "\n", + "\\begin{align}\n", + "\\log\\tilde{p}(\\boldsymbol{f}|\\mathcal{D}) = \\log\\tilde{p}(\\hat{\\boldsymbol{f}}|\\mathcal{D}) + \\left[\\nabla \\log\\tilde{p}({\\boldsymbol{f}}|\\mathcal{D})|_{\\hat{\\boldsymbol{f}}}\\right]^{T} (\\boldsymbol{f}-\\hat{\\boldsymbol{f}}) + \\frac{1}{2} (\\boldsymbol{f}-\\hat{\\boldsymbol{f}})^{T} \\left[\\nabla^2 \\tilde{p}(\\boldsymbol{y}|\\boldsymbol{f})|_{\\hat{\\boldsymbol{f}}} \\right] (\\boldsymbol{f}-\\hat{\\boldsymbol{f}}) + \\mathcal{O}(\\lVert \\boldsymbol{f} - \\hat{\\boldsymbol{f}} \\rVert^3).\n", + "\\end{align}\n", + "\n", + "Since $\\nabla \\log\\tilde{p}({\\boldsymbol{f}}|\\mathcal{D})$ is zero at the mode,\n", + "this suggests the following approximation\n", + "\\begin{align}\n", + "\\tilde{p}(\\boldsymbol{f}|\\mathcal{D}) \\approx \\log\\tilde{p}(\\hat{\\boldsymbol{f}}|\\mathcal{D}) \\exp\\left\\{ \\frac{1}{2} (\\boldsymbol{f}-\\hat{\\boldsymbol{f}})^{T} \\left[-\\nabla^2 \\tilde{p}(\\boldsymbol{y}|\\boldsymbol{f})|_{\\hat{\\boldsymbol{f}}} \\right] (\\boldsymbol{f}-\\hat{\\boldsymbol{f}}) \\right\\}\n", + "\\end{align},\n", + "\n", + "that we identify as a Gaussian distribution,\n", + "$p(\\boldsymbol{f}| \\mathcal{D}) \\approx q(\\boldsymbol{f}) := \\mathcal{N}(\\hat{\\boldsymbol{f}}, [-\\nabla^2 \\tilde{p}(\\boldsymbol{y}|\\boldsymbol{f})|_{\\hat{\\boldsymbol{f}}} ]^{-1} )$.\n", + "Since the negative Hessian is positive definite, we can use the Cholesky\n", + "decomposition to obtain the covariance matrix of the Laplace approximation at the\n", + "datapoints below." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4f96ede8", + "metadata": { + "lines_to_next_cell": 2 + }, + "outputs": [], + "source": [ + "import cola\n", + "from gpjax.lower_cholesky import lower_cholesky\n", + "\n", + "gram, cross_covariance = (kernel.gram, kernel.cross_covariance)\n", + "jitter = 1e-6\n", + "\n", + "# Compute (latent) function value map estimates at training points:\n", + "Kxx = opt_posterior.prior.kernel.gram(x)\n", + "Kxx += identity_matrix(D.n) * jitter\n", + "Kxx = cola.PSD(Kxx)\n", + "Lx = lower_cholesky(Kxx)\n", + "f_hat = Lx @ opt_posterior.latent\n", + "\n", + "# Negative Hessian, H = -∇²p_tilde(y|f):\n", + "H = jax.jacfwd(jax.jacrev(negative_lpd))(opt_posterior, D).latent.latent[:, 0, :, 0]\n", + "\n", + "L = jnp.linalg.cholesky(H + identity_matrix(D.n) * jitter)\n", + "\n", + "# H⁻¹ = H⁻¹ I = (LLᵀ)⁻¹ I = L⁻ᵀL⁻¹ I\n", + "L_inv = jsp.linalg.solve_triangular(L, identity_matrix(D.n), lower=True)\n", + "H_inv = jsp.linalg.solve_triangular(L.T, L_inv, lower=False)\n", + "LH = jnp.linalg.cholesky(H_inv)\n", + "laplace_approximation = tfd.MultivariateNormalTriL(f_hat.squeeze(), LH)" + ] + }, + { + "cell_type": "markdown", + "id": "1b21f9c7", + "metadata": { + "lines_to_next_cell": 2 + }, + "source": [ + "For novel inputs, we must project the above approximating distribution through the\n", + "Gaussian conditional distribution $p(f(\\cdot)| \\boldsymbol{f})$,\n", + "\n", + "\\begin{align}\n", + "p(f(\\cdot)| \\mathcal{D}) \\approx q_{Laplace}(f(\\cdot)) := \\int p(f(\\cdot)| \\boldsymbol{f}) q(\\boldsymbol{f}) d \\boldsymbol{f} = \\mathcal{N}(\\mathbf{K}_{\\boldsymbol{(\\cdot)x}} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} \\hat{\\boldsymbol{f}}, \\mathbf{K}_{\\boldsymbol{(\\cdot, \\cdot)}} - \\mathbf{K}_{\\boldsymbol{(\\cdot)\\boldsymbol{x}}} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} (\\mathbf{K}_{\\boldsymbol{xx}} - [-\\nabla^2 \\tilde{p}(\\boldsymbol{y}|\\boldsymbol{f})|_{\\hat{\\boldsymbol{f}}} ]^{-1}) \\mathbf{K}_{\\boldsymbol{xx}}^{-1} \\mathbf{K}_{\\boldsymbol{\\boldsymbol{x}(\\cdot)}}).\n", + "\\end{align}\n", + "\n", + "This is the same approximate distribution $q_{map}(f(\\cdot))$, but we have perturbed\n", + "the covariance by a curvature term of\n", + "$\\mathbf{K}_{\\boldsymbol{(\\cdot)\\boldsymbol{x}}} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} [-\\nabla^2 \\tilde{p}(\\boldsymbol{y}|\\boldsymbol{f})|_{\\hat{\\boldsymbol{f}}} ]^{-1} \\mathbf{K}_{\\boldsymbol{xx}}^{-1} \\mathbf{K}_{\\boldsymbol{\\boldsymbol{x}(\\cdot)}}$.\n", + "We take the latent distribution computed in the previous section and add this term\n", + "to the covariance to construct $q_{Laplace}(f(\\cdot))$." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4021889b", + "metadata": {}, + "outputs": [], + "source": [ + "def construct_laplace(test_inputs: Float[Array, \"N D\"]) -> tfd.MultivariateNormalTriL:\n", + " map_latent_dist = opt_posterior.predict(xtest, train_data=D)\n", + "\n", + " Kxt = opt_posterior.prior.kernel.cross_covariance(x, test_inputs)\n", + " Kxx = opt_posterior.prior.kernel.gram(x)\n", + " Kxx += identity_matrix(D.n) * jitter\n", + " Kxx = cola.PSD(Kxx)\n", + "\n", + " # Kxx⁻¹ Kxt\n", + " Kxx_inv_Kxt = cola.solve(Kxx, Kxt)\n", + "\n", + " # Ktx Kxx⁻¹[ H⁻¹ ] Kxx⁻¹ Kxt\n", + " laplace_cov_term = jnp.matmul(jnp.matmul(Kxx_inv_Kxt.T, H_inv), Kxx_inv_Kxt)\n", + "\n", + " mean = map_latent_dist.mean()\n", + " covariance = map_latent_dist.covariance() + laplace_cov_term\n", + " L = jnp.linalg.cholesky(covariance)\n", + " return tfd.MultivariateNormalTriL(jnp.atleast_1d(mean.squeeze()), L)" + ] + }, + { + "cell_type": "markdown", + "id": "6458ec70", + "metadata": { + "lines_to_next_cell": 0 + }, + "source": [ + "From this we can construct the predictive distribution at the test points." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "73ba0f59", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "laplace_latent_dist = construct_laplace(xtest)\n", + "predictive_dist = opt_posterior.likelihood(laplace_latent_dist)\n", + "\n", + "predictive_mean = predictive_dist.mean()\n", + "predictive_std = predictive_dist.stddev()\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.scatter(x, y, label=\"Observations\", color=cols[0])\n", + "ax.plot(xtest, predictive_mean, label=\"Predictive mean\", color=cols[1])\n", + "ax.fill_between(\n", + " xtest.squeeze(),\n", + " predictive_mean - predictive_std,\n", + " predictive_mean + predictive_std,\n", + " alpha=0.2,\n", + " color=cols[1],\n", + " label=\"One sigma\",\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean - predictive_std,\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " predictive_mean + predictive_std,\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "ax.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "6d10a99b", + "metadata": {}, + "source": [ + "However, the Laplace approximation is still limited by considering information about\n", + "the posterior at a single location. On the other hand, through approximate sampling,\n", + "MCMC methods allow us to learn all information about the posterior distribution." + ] + }, + { + "cell_type": "markdown", + "id": "b22b9996", + "metadata": {}, + "source": [ + "## MCMC inference\n", + "\n", + "An MCMC sampler works by starting at an initial position and\n", + "drawing a sample from a cheap-to-simulate distribution known as the _proposal_. The\n", + "next step is to determine whether this sample could be considered a draw from the\n", + "posterior. We accomplish this using an _acceptance probability_ determined via the\n", + "sampler's _transition kernel_ which depends on the current position and the\n", + "unnormalised target posterior distribution. If the new sample is more _likely_, we\n", + "accept it; otherwise, we reject it and stay in our current position. Repeating these\n", + "steps results in a Markov chain (a random sequence that depends only on the last\n", + "state) whose stationary distribution (the long-run empirical distribution of the\n", + "states visited) is the posterior. For a gentle introduction, see the first chapter\n", + "of [A Handbook of Markov Chain Monte Carlo](https://www.mcmchandbook.net/HandbookChapter1.pdf).\n", + "\n", + "### MCMC through BlackJax\n", + "\n", + "Rather than implementing a suite of MCMC samplers, GPJax relies on MCMC-specific\n", + "libraries for sampling functionality. We focus on\n", + "[BlackJax](https://github.com/blackjax-devs/blackjax/) in this notebook, which we\n", + "recommend adopting for general applications.\n", + "\n", + "We'll use the No U-Turn Sampler (NUTS) implementation given in BlackJax for sampling.\n", + "For the interested reader, NUTS is a Hamiltonian Monte Carlo sampling scheme where\n", + "the number of leapfrog integration steps is computed at each step of the change\n", + "according to the NUTS algorithm. In general, samplers constructed under this\n", + "framework are very efficient.\n", + "\n", + "We begin by generating _sensible_ initial positions for our sampler before defining\n", + "an inference loop and sampling 500 values from our Markov chain. In practice,\n", + "drawing more samples will be necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1fd8042b", + "metadata": {}, + "outputs": [], + "source": [ + "num_adapt = 500\n", + "num_samples = 500\n", + "\n", + "lpd = jax.jit(gpx.LogPosteriorDensity(negative=False))\n", + "unconstrained_lpd = jax.jit(lambda tree: lpd(tree.constrain(), D))\n", + "\n", + "adapt = blackjax.window_adaptation(\n", + " blackjax.nuts, unconstrained_lpd, num_adapt, target_acceptance_rate=0.65\n", + ")\n", + "\n", + "# Initialise the chain\n", + "start = time()\n", + "last_state, kernel, _ = adapt.run(key, posterior.unconstrain())\n", + "print(f\"Adaption time taken: {time() - start: .1f} seconds\")\n", + "\n", + "\n", + "def inference_loop(rng_key, kernel, initial_state, num_samples):\n", + " def one_step(state, rng_key):\n", + " state, info = kernel(rng_key, state)\n", + " return state, (state, info)\n", + "\n", + " keys = jax.random.split(rng_key, num_samples)\n", + " _, (states, infos) = jax.lax.scan(one_step, initial_state, keys)\n", + "\n", + " return states, infos\n", + "\n", + "\n", + "# Sample from the posterior distribution\n", + "start = time()\n", + "states, infos = inference_loop(key, kernel, last_state, num_samples)\n", + "print(f\"Sampling time taken: {time() - start: .1f} seconds\")" + ] + }, + { + "cell_type": "markdown", + "id": "d0cf235c", + "metadata": {}, + "source": [ + "### Sampler efficiency\n", + "\n", + "BlackJax gives us easy access to our sampler's efficiency through metrics such as the\n", + "sampler's _acceptance probability_ (the number of times that our chain accepted a\n", + "proposed sample, divided by the total number of steps run by the chain). For NUTS and\n", + "Hamiltonian Monte Carlo sampling, we typically seek an acceptance rate of 60-70% to\n", + "strike the right balance between having a chain which is _stuck_ and rarely moves\n", + "versus a chain that is too jumpy with frequent small steps." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c9a7f7f", + "metadata": {}, + "outputs": [], + "source": [ + "acceptance_rate = jnp.mean(infos.acceptance_probability)\n", + "print(f\"Acceptance rate: {acceptance_rate:.2f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "6eae2e0a", + "metadata": {}, + "source": [ + "Our acceptance rate is slightly too large, prompting an examination of the chain's\n", + "trace plots. A well-mixing chain will have very few (if any) flat spots in its trace\n", + "plot whilst also not having too many steps in the same direction. In addition to\n", + "the model's hyperparameters, there will be 500 samples for each of the 100 latent\n", + "function values in the `states.position` dictionary. We depict the chains that\n", + "correspond to the model hyperparameters and the first value of the latent function\n", + "for brevity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9328818", + "metadata": {}, + "outputs": [], + "source": [ + "fig, (ax0, ax1, ax2) = plt.subplots(ncols=3, figsize=(10, 3))\n", + "ax0.plot(states.position.prior.kernel.lengthscale)\n", + "ax1.plot(states.position.prior.kernel.variance)\n", + "ax2.plot(states.position.latent[:, 1, :])\n", + "ax0.set_title(\"Kernel Lengthscale\")\n", + "ax1.set_title(\"Kernel Variance\")\n", + "ax2.set_title(\"Latent Function (index = 1)\")" + ] + }, + { + "cell_type": "markdown", + "id": "f875f762", + "metadata": {}, + "source": [ + "## Prediction\n", + "\n", + "Having obtained samples from the posterior, we draw ten instances from our model's\n", + "predictive distribution per MCMC sample. Using these draws, we will be able to\n", + "compute credible values and expected values under our posterior distribution.\n", + "\n", + "An ideal Markov chain would have samples completely uncorrelated with their\n", + "neighbours after a single lag. However, in practice, correlations often exist\n", + "within our chain's sample set. A commonly used technique to try and reduce this\n", + "correlation is _thinning_ whereby we select every $n$th sample where $n$ is the\n", + "minimum lag length at which we believe the samples are uncorrelated. Although further\n", + "analysis of the chain's autocorrelation is required to find appropriate thinning\n", + "factors, we employ a thin factor of 10 for demonstration purposes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc1730a3", + "metadata": {}, + "outputs": [], + "source": [ + "thin_factor = 20\n", + "posterior_samples = []\n", + "\n", + "for i in trange(0, num_samples, thin_factor, desc=\"Drawing posterior samples\"):\n", + " sample = jtu.tree_map(lambda samples, i=i: samples[i], states.position)\n", + " sample = sample.constrain()\n", + " latent_dist = sample.predict(xtest, train_data=D)\n", + " predictive_dist = sample.likelihood(latent_dist)\n", + " posterior_samples.append(predictive_dist.sample(seed=key, sample_shape=(10,)))\n", + "\n", + "posterior_samples = jnp.vstack(posterior_samples)\n", + "lower_ci, upper_ci = jnp.percentile(posterior_samples, jnp.array([2.5, 97.5]), axis=0)\n", + "expected_val = jnp.mean(posterior_samples, axis=0)" + ] + }, + { + "cell_type": "markdown", + "id": "43b956b0", + "metadata": {}, + "source": [ + "\n", + "Finally, we end this tutorial by plotting the predictions obtained from our model\n", + "against the observed data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8a65948", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.scatter(x, y, color=cols[0], label=\"Observations\", zorder=2, alpha=0.7)\n", + "ax.plot(xtest, expected_val, color=cols[1], label=\"Predicted mean\", zorder=1)\n", + "ax.fill_between(\n", + " xtest.flatten(),\n", + " lower_ci.flatten(),\n", + " upper_ci.flatten(),\n", + " alpha=0.2,\n", + " color=cols[1],\n", + " label=\"95\\\\% CI\",\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " lower_ci.flatten(),\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "ax.plot(\n", + " xtest,\n", + " upper_ci.flatten(),\n", + " color=cols[1],\n", + " linestyle=\"--\",\n", + " linewidth=1,\n", + ")\n", + "ax.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "b9c17a58", + "metadata": {}, + "source": [ + "## System configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a84586dc", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext watermark\n", + "%watermark -n -u -v -iv -w -a \"Thomas Pinder & Daniel Dodd\"" + ] + } + ], + "metadata": { + "jupytext": { + "cell_metadata_filter": "-all", + "custom_cell_magics": "kql", + "encoding": "# -*- coding: utf-8 -*-" + }, + "kernelspec": { + "display_name": "gpjax", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/examples/classification.py b/docs/examples/classification.py index 22c7107d5..0f85e8580 100644 --- a/docs/examples/classification.py +++ b/docs/examples/classification.py @@ -255,16 +255,12 @@ def construct_laplace(test_inputs: Float[Array, "N D"]) -> tfd.MultivariateNorma Kxx = opt_posterior.prior.kernel.gram(x) Kxx += identity_matrix(D.n) * jitter Kxx = cola.PSD(Kxx) - Lx = lower_cholesky(Kxx) - - # Lx⁻¹ Kxt - Lx_inv_Ktx = Lx.solve(Kxt) # Kxx⁻¹ Kxt - Kxx_inv_Ktx = Lx.T.solve(Lx_inv_Ktx) + Kxx_inv_Kxt = cola.solve(Kxx, Kxt) # Ktx Kxx⁻¹[ H⁻¹ ] Kxx⁻¹ Kxt - laplace_cov_term = jnp.matmul(jnp.matmul(Kxx_inv_Ktx.T, H_inv), Kxx_inv_Ktx) + laplace_cov_term = jnp.matmul(jnp.matmul(Kxx_inv_Kxt.T, H_inv), Kxx_inv_Kxt) mean = map_latent_dist.mean() covariance = map_latent_dist.covariance() + laplace_cov_term diff --git a/gpjax/objectives.py b/gpjax/objectives.py index 2f6d7cd91..7851cef62 100644 --- a/gpjax/objectives.py +++ b/gpjax/objectives.py @@ -14,6 +14,7 @@ ) from gpjax.dataset import Dataset from gpjax.gaussian_distribution import GaussianDistribution +from gpjax.lower_cholesky import lower_cholesky from gpjax.typing import ( Array, ScalarFloat, @@ -175,7 +176,7 @@ def step( Kxx = posterior.prior.kernel.gram(x) Kxx += cola.ops.I_like(Kxx) * posterior.prior.jitter Kxx = cola.PSD(Kxx) - Lx = cola.sqrt(Kxx) + Lx = lower_cholesky(Kxx) # Compute the prior mean function mx = posterior.prior.mean_function(x) @@ -338,7 +339,7 @@ def step( Kxx_diag = vmap(kernel, in_axes=(0, 0))(x, x) μx = mean_function(x) - Lz = cola.sqrt(Kzz) + Lz = lower_cholesky(Kzz) # Notation and derivation: # From 082de968de221375f3e0e95816cb3d3c3e4f6dc6 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 17:47:19 +0100 Subject: [PATCH 68/76] Replace log-determinants with "dense" solve - seems like an issue with CoLA. --- gpjax/gaussian_distribution.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gpjax/gaussian_distribution.py b/gpjax/gaussian_distribution.py index f077f6031..a5ad870ca 100644 --- a/gpjax/gaussian_distribution.py +++ b/gpjax/gaussian_distribution.py @@ -152,7 +152,9 @@ def entropy(self) -> ScalarFloat: r"""Calculates the entropy of the distribution.""" return 0.5 * ( self.event_shape[0] * (1.0 + jnp.log(2.0 * jnp.pi)) - + cola.logdet(self.scale) + + cola.logdet( + self.scale, method="dense" + ) # <--- Seems to be an issue with CoLA! ) def log_prob( @@ -186,7 +188,7 @@ def log_prob( # compute the pdf, -1/2[ n log(2π) + log|Σ| + (y - µ)ᵀΣ⁻¹(y - µ) ] return -0.5 * ( n * jnp.log(2.0 * jnp.pi) - + cola.logdet(sigma) + + cola.logdet(sigma, method="dense") # <--- Seems to be an issue with CoLA! + diff.T @ cola.solve(sigma, diff) ) From 5d9a43db3487d438d1a0a2253a35bfed33610a86 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Wed, 6 Sep 2023 18:05:01 +0100 Subject: [PATCH 69/76] Prepare for future batching In the future certain utility functions will be "batched" utility functions which quantify the utility of querying a *batch* of points rather than a single point. These utility functions may in turn be optimised differently. Therefore, I propose we have a `SinglePointUtilityFunction` type for non-batched utility functions, which has type annotation `[N D] -> [N 1]`, and in the future we may add `BatchUtilityFunction` which has type annotation `[N B D] -> [N 1]`. Distinguishing between these makes it easy for users to see which utility functions support batching. Also refactored UtilityDrivenDecisionMaker to enable for Thompson sampling to be used in a batched context, and updated unit tests to reflect this. Finally, added a new notebook to serve as an introduction to the `decision_making` module. --- docs/examples/decision_making.py | 387 ++++++++++++++++++ gpjax/decision_making/__init__.py | 10 +- gpjax/decision_making/decision_maker.py | 92 ++++- .../utility_functions/__init__.py | 4 + .../decision_making/utility_functions/base.py | 29 +- .../utility_functions/thompson_sampling.py | 20 +- gpjax/decision_making/utility_maximizer.py | 24 +- mkdocs.yml | 1 + .../test_decision_maker.py | 206 ++++++++-- .../test_utility_maximizer.py | 22 +- tests/test_decision_making/utils.py | 12 +- 11 files changed, 727 insertions(+), 80 deletions(-) create mode 100644 docs/examples/decision_making.py diff --git a/docs/examples/decision_making.py b/docs/examples/decision_making.py new file mode 100644 index 000000000..28d441cbd --- /dev/null +++ b/docs/examples/decision_making.py @@ -0,0 +1,387 @@ +# %% [markdown] +# # Introduction to Decision Making with GPJax +# +# In this notebook we provide an introduction to the decision making module of GPJax, +# which can be used to solve sequential decision making problems. Common examples of +# such problems include Bayesian optimisation (BO) and experimental design. For an +# in-depth introduction to Bayesian optimisation itself, be sure to checkout out our +# [Introduction to BO +# Notebook](https://docs.jaxgaussianprocesses.com/examples/bayesian_optimisation/). +# +# We'll be using BO as a case study to demonstrate how one may use the decision making +# module to solve sequential decision making problems. The goal of the decision making +# module is to provide a set of tools that can easily be used to solve a wide range of +# sequential decision making problems. The module is designed to be modular, and so it is +# easy to swap out different components of the decision making pipeline. Whilst it +# provides the functionality for quickly implementing a typical deicision making loop out +# of the box, we also hope that it will provide sufficient flexibility to allow users to +# define their own, more exotic, decision making pipelines. + +# %% +# Enable Float64 for more stable matrix inversions. +from jax import config + +config.update("jax_enable_x64", True) + + +import jax.numpy as jnp +import jax.random as jr +import matplotlib as mpl +import matplotlib.pyplot as plt +import optax as ox + +import gpjax as gpx +from gpjax.decision_making.utility_functions import ( + ThompsonSampling, +) +from gpjax.decision_making.utility_maximizer import ( + ContinuousSinglePointUtilityMaximizer, +) +from gpjax.decision_making.decision_maker import UtilityDrivenDecisionMaker +from gpjax.decision_making.utils import ( + OBJECTIVE, + build_function_evaluator, +) +from gpjax.decision_making.posterior_handler import PosteriorHandler +from gpjax.decision_making.search_space import ContinuousSearchSpace +from gpjax.typing import ( + Array, + Float, +) + +key = jr.PRNGKey(42) +plt.style.use( + "https://raw.githubusercontent.com/JaxGaussianProcesses/GPJax/main/docs/examples/gpjax.mplstyle" +) +cols = mpl.rcParams["axes.prop_cycle"].by_key()["color"] + + +# %% [markdown] +# ## The Black-Box Objective Function +# +# We'll be using the same problem as in the [Introduction to BO +# Notebook](https://docs.jaxgaussianprocesses.com/examples/bayesian_optimisation/), but +# rather than focussing on the mechanics of BO we'll be looking at how one may use the +# abstractions provided by the decision making module to implement the BO loop. +# +# In BO, and sequential decision making in general, we will often have a black-box +# function of interest which we can evaluate. In this notebook we'll be using the +# Forrester function as our objective to minimise: +# +# $$f(x) = (6x - 2)^2\sin(12x-4)$$ + + +# %% +def forrester(x: Float[Array, "N 1"]) -> Float[Array, "N 1"]: + return (6 * x - 2) ** 2 * jnp.sin(12 * x - 4) + + +# %% [markdown] +# Within the decision making loop, we'll be querying the black-box objective function many +# times, and will often use the observed values to fit some probabilistic model. Thereore, +# it would be useful to have some method to which we can pass a set of points which we +# wish to query the black-box function at, and which will return a GPJax `Dataset` object +# containing the observations. We can use the `build_function_evaluator` function provided +# in `decision_making.utils` to do this. This function takes as input a dictionary of +# labelled black-box functions, and will return a function evaluator, which can be called +# with a set of points to evaluate the black-box functions at. The function evaluator will +# return a dictionary of labelled `Dataset` objects containing the observations. Note that +# in our case we only have one black-box function of interest, but in general we may have +# multiple different black-box functions, such as if we also have constraint functions. +# The use of the labels inside the dictionary returned by the function evaluator enables +# us to easily distinguish between these different observations. + +# %% +function_evaluator = build_function_evaluator({OBJECTIVE: forrester}) + +# %% [markdown] +# ## The Search Space +# +# Having defined a method for evaluating the black-box function, we now need to define the +# search space over which we wish to optimise. In this case we'll be optimising over the +# interval $[0, 1]$. We can use the `ContinuousSearchSpace` class provided in +# `decision_making.search_space` to define this search space, as seen below: + +# %% +lower_bounds = jnp.array([0.0]) +upper_bounds = jnp.array([1.0]) +search_space = ContinuousSearchSpace( + lower_bounds=lower_bounds, upper_bounds=upper_bounds +) + +# %% [markdown] +# The `ContinuousSearchSpace` class defines a `sample` method, which can be used to +# sample points from the search space using a space-filling design, in this case using the +# [Halton sequence](https://en.wikipedia.org/wiki/Halton_sequence). This will be useful at +# many points throughout the decision making loop, but for now let's use it to create an +# initial set of points which we can use to fit our models: + +# %% +initial_x = search_space.sample(5, key) +initial_datasets = function_evaluator(initial_x) + +# %% [markdown] +# ## The Surrogate Models + +# %% [markdown] +# Many sequential decision making algorithms are described as being *model-based*. With +# these algorithms, we use a probabilistic model, or multiple models, to drive the +# decision making process. In ordinary BO, a probabilistic model is used to model the +# objective function, and it is updated based on observations from the black-box objective +# function. These models are often referred to as *surrogate models*, and are used to +# approximate the functions of interest. We'll be using the Gaussian process functionality +# provided by GPJax to define our surrogate models, with some wrappers provided by the +# `decision_making` module to make it easier to use these models within the decision +# making loop. We can proceed as usual when defining our priors, choosing a suitable +# mean function and kernel for the job at hand: + +# %% +mean = gpx.Zero() +kernel = gpx.Matern52() +prior = gpx.Prior(mean_function=mean, kernel=kernel) + +# %% [markdown] +# One difference from GPJax is the way in which we define our likelihood. In GPJax, we +# construct our GP posteriors by defining a `likelihood` object and then multiplying it +# with our prior to get the posterior, `posterior = likelihood * prior`. However, the +# `AbstractLikelihood` objects takes `num_datapoints` as one of its arguments, and this is +# going to be changing in the case of BO, and decision making in general, as we keep +# updating our models having observed new data! In order to deal with this we'll define a +# `likelihood_builder`, which takes as an argument the number of datapoints used to +# condition our prior on, and returns a `likelihood` object. Below we use this to +# construct a `likelihood_builder` which will return a `Gaussian` likelihood, initialised +# with the correct number of datapoints: + +# %% +likelihood_builder = lambda n: gpx.Gaussian(num_datapoints=n, obs_noise=jnp.array(1e-6)) + +# %% [markdown] +# Now we have all the components required for constructing our GP posterior. Since we'll +# be updating the posterior throughout the decision making loop as we observe more data, +# it would be useful to have an object which can handle all this logic for us. +# Fortunately, the `decision_making` module provides the `PosteriorHandler` class to do +# this for us. This class takes as input a `prior` and `likeligood_builder`, which we have +# defined above. We tend to also optimise the hyperparameters of the GP prior when +# "fitting" our GP, as demonstrated in the [Regression +# notebook](https://docs.jaxgaussianprocesses.com/examples/regression/). This will be +# using the GPJax `fit` method under the hood, which requires an `optimization_objective`, +# `optimizer` and `num_optimization_iters`. Therefore, we also pass these to the +# `PosteriorHandler` as demonstrated below: + +# %% +posterior_handler = PosteriorHandler( + prior, + likelihood_builder=likelihood_builder, + optimization_objective=gpx.ConjugateMLL(negative=True), + optimizer=ox.adam(learning_rate=0.01), + num_optimization_iters=1000, +) +posterior_handlers = {OBJECTIVE: posterior_handler} + +# %% [markdown] +# Note that we also create a labelled dictionary of `posterior_handlers`. This is a +# recurring theme with the decision making logic; we can have dictionaries containing +# datasets, posteriors and black box functions, and use labels to identify corresponding +# objects the dictionaries. For instance, here we have an "OBJECTIVE" posterior handler +# which is updated using the data in the "OBJECTIVE" dataset, which is in turn generated by the "OBJECTIVE" black-box function. +# +# Now, as the decision making loop progresses, we can use the `update_posterior` method of +# the `PosteriorHandler` to update our posterior as we observe more data. Note that we use +# the term *posterior* to refer to our GP posterior surrogate models in order to be +# consistent with the syntax used by GPJax. However, these GP posteriors are more widely +# referred to as *models* in the model-based decision making literature. + +# %% [markdown] +# ## The Utility Function +# +# Now all that remains for us to define is the utiliy function, and a way of maximising +# it. Within the utility-driven decision making framework, we define a utility function, +# often using our GP surrogates, which characterises the *utility*, or *usefulness*, of +# querying the black-box function at any point within the domain of interest. We can then +# *maximise* this function to decide which point to query next. In this case we'll be +# using Thompson sampling as a utility function for determining where to query next. With +# this function we simply draw a sample from the GP posterior, and choose the minimizer +# of the sample as the point to query next. In the `decision_making` framework we create +# `UtilityFunctionBuilder` objects. Currently, we only support +# `SinglePointUtilityFunction`s, which are utility functions which characterise the +# utility of querying a single point. Thompson sampling is somewhat of a special case, as +# we can draw $B$ independent samples from the GP posterior and optimise each of these +# samples in order to obtain a *batch* of points to query next. We'll see an example of +# this later on. +# +# Within the `ThompsonSampling` utility function builder class we implement the +# `build_utility_function` method, which takes as input a dictionary containing lablled GP +# posteriors, as well as the corresponding datasets for these posteriors, and draws an +# approximate sample from the GP posterior which is a surrogate for the objective +# function. We instantiate our utility function builder below, specifying the number of +# Random Fourier features to use when constructing the approximate samples from the GP posterior: + +# %% +utility_function_builder = ThompsonSampling(num_features=500) + +# %% [markdown] +# We also need a method for maximising the utility function. Since `ThompsonSampling` is +# classed as a `SinglePointUtilityFunction`, we can use the +# `ContinuousSinglePointUtilityMaximizer` to maximise it. This requires the user to +# specify `num_initial_samples` and `num_restarts` when instantiating it. This first +# queries the utility function at `num_initial_samples` points, and then uses the best of +# these points as a starting point for L-BFGS-B, a gradient-based optimiser, to further +# refine. This is repeated `num_restarts` times, each time sampling a different initial set +# of `num_initial_samples` and the best point found is returned. We'll instantiate our +# maximiser below: + +# %% +acquisition_maximizer = ContinuousSinglePointUtilityMaximizer( + num_initial_samples=100, num_restarts=1 +) + + +# %% [markdown] +# ## Putting it All Together with the Decision Maker +# +# We now have all the ingredients ready for our Bayesian optimisation loop, so let's put +# all the logic together using the `UtilityDrivenDecisionMaker` class provided by the +# `decision_making` module. This class has 3 core methods: +# 1. `ask` - This method is used to decide which point(s) to query next. +# 2. `tell` - This method is used to tell the decision maker the results from querying the +# black-box function at the points returned by `ask`, and will often update GP +# posteriors in light of this data. +# 3. `run` - This is used to run the decision making loop for a specified number of +# iterations, alternating between `ask` and `tell`. +# +# For many decision making problems, the logic provided in the +# `UtilityDrivenDecisionMaker` will be sufficient, and is a convenient way of gluing the +# various bits of machinery involved in sequential decision making together. However, for +# more exotic decision making loops, it is easy for the user to define their own decision +# maker class by inheriting from the `AbstractDecisionMaker` class and defining their own +# `ask`, `tell` and `run` methods. +# +# However, we do also provide the user with some additional flexibility when using the +# `UtilityDrivenDecisionMaker` class. Often we may wish to perform certain actions after +# the `ask` step and the `tell` step, such as plotting the acquisition function and the +# point chosen to be queried for debugging purposes. We can do this by passing a list of +# functions to be called at each of these points as the `post_ask` and `post_tell` +# attributes of the `UtilityDrivenDecisionMaker`. Both sets of functions are called with +# the `UtilityDrivenDecisionMaker` as an argument, and so have access to all the +# attributes of the decision maker. The `post_ask` functions are additionally passed the +# most recently queried points too. We'll use this functionality to plot the acquisition +# function and the point chosen to be queried at each step of the decision making loop: + + +# %% +def plot_bo_iteration( + dm: UtilityDrivenDecisionMaker, last_queried_points: Float[Array, "B D"] +): + posterior = dm.posteriors[OBJECTIVE] + dataset = dm.datasets[OBJECTIVE] + plt_x = jnp.linspace(0, 1, 1000).reshape(-1, 1) + forrester_y = forrester(plt_x.squeeze(axis=-1)) + utility_fn = dm.current_utility_functions[0] + sample_y = -utility_fn(plt_x) + + latent_dist = posterior.predict(plt_x, train_data=dataset) + predictive_dist = posterior.likelihood(latent_dist) + + predictive_mean = predictive_dist.mean() + predictive_std = predictive_dist.stddev() + + fig, ax = plt.subplots() + ax.plot(plt_x.squeeze(), predictive_mean, label="Predictive Mean", color=cols[1]) + ax.fill_between( + plt_x.squeeze(), + predictive_mean - 2 * predictive_std, + predictive_mean + 2 * predictive_std, + alpha=0.2, + label="Two sigma", + color=cols[1], + ) + ax.plot( + plt_x.squeeze(), + predictive_mean - 2 * predictive_std, + linestyle="--", + linewidth=1, + color=cols[1], + ) + ax.plot( + plt_x.squeeze(), + predictive_mean + 2 * predictive_std, + linestyle="--", + linewidth=1, + color=cols[1], + ) + ax.plot(plt_x.squeeze(), sample_y, label="Posterior Sample") + ax.plot( + plt_x.squeeze(), + forrester_y, + label="Forrester Function", + color=cols[0], + linestyle="--", + linewidth=2, + ) + ax.axvline(x=0.757, linestyle=":", color=cols[3], label="True Optimum") + ax.scatter(dataset.X, dataset.y, label="Observations", color=cols[2], zorder=2) + ax.scatter( + last_queried_points[0], + -utility_fn(last_queried_points[0][None, ...]), + label="Posterior Sample Optimum", + marker="*", + color=cols[3], + zorder=3, + ) + ax.legend(loc="center left", bbox_to_anchor=(0.950, 0.5)) + plt.show() + + +# %% [markdown] +# Now let's put it all together and run our decision making loop for 6 iterations, with a +# batch size of 1: + +# %% +dm = UtilityDrivenDecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=initial_datasets, + utility_function_builder=utility_function_builder, + utility_maximizer=acquisition_maximizer, + batch_size=1, + key=key, + post_ask=[plot_bo_iteration], + post_tell=[], +) + +results = dm.run( + 6, + black_box_function_evaluator=function_evaluator, +) + +# %% [markdown] +# We can see that our `DecisionMaker` is successfully able to find the minimimizer of the +# black box function! +# +# + +# %% [markdown] +# ## Conclusions + +# %% [markdown] +# In this notebook we have provided an introduction to the new `decision_making` module of +# GPJax. We have demonstrated how one may use the abstractions provided by this module to +# implement a Bayesian optimisation loop, and have also highlighted some of the +# flexibility provided by the module. We hope that this module will provide a useful +# framework for solving a wide range of sequential decision making problems, and that it +# will be easy for users to extend the functionality provided by the module to suit their +# needs! +# +# We should note that the `decision_making` module is still in its early stages, and so +# whilst we hope to avoid making breaking changes to it, they may occur as the module +# evolves and more advanced functionality is implemented. If people have any feedback or +# features they would like to implement/see implemented, feel free to open an issue on the +# [GPJax GitHub page](https://github.com/JaxGaussianProcesses/GPJax/issues). +# + +# %% [markdown] +# ## System Configuration + +# %% +# %reload_ext watermark +# %watermark -n -u -v -iv -w -a 'Thomas Christie' diff --git a/gpjax/decision_making/__init__.py b/gpjax/decision_making/__init__.py index 5c782a3a4..4fd8a45af 100644 --- a/gpjax/decision_making/__init__.py +++ b/gpjax/decision_making/__init__.py @@ -28,13 +28,16 @@ Quadratic, ) from gpjax.decision_making.utility_functions import ( + AbstractSinglePointUtilityFunctionBuilder, AbstractUtilityFunctionBuilder, + SinglePointUtilityFunction, ThompsonSampling, UtilityFunction, ) from gpjax.decision_making.utility_maximizer import ( + AbstractSinglePointUtilityMaximizer, AbstractUtilityMaximizer, - ContinuousUtilityMaximizer, + ContinuousSinglePointUtilityMaximizer, ) from gpjax.decision_making.utils import build_function_evaluator @@ -43,9 +46,11 @@ "AbstractUtilityMaximizer", "AbstractDecisionMaker", "AbstractSearchSpace", + "AbstractSinglePointUtilityFunctionBuilder", + "AbstractSinglePointUtilityMaximizer", "UtilityFunction", "build_function_evaluator", - "ContinuousUtilityMaximizer", + "ContinuousSinglePointUtilityMaximizer", "ContinuousSearchSpace", "UtilityDrivenDecisionMaker", "AbstractContinuousTestFunction", @@ -53,5 +58,6 @@ "LogarithmicGoldsteinPrice", "PosteriorHandler", "Quadratic", + "SinglePointUtilityFunction", "ThompsonSampling", ] diff --git a/gpjax/decision_making/decision_maker.py b/gpjax/decision_making/decision_maker.py index 255a6b23a..ca4709dac 100644 --- a/gpjax/decision_making/decision_maker.py +++ b/gpjax/decision_making/decision_maker.py @@ -16,6 +16,7 @@ ABC, abstractmethod, ) +import copy from dataclasses import dataclass from beartype.typing import ( @@ -24,12 +25,16 @@ List, Mapping, ) +import jax.numpy as jnp import jax.random as jr from gpjax.dataset import Dataset from gpjax.decision_making.posterior_handler import PosteriorHandler from gpjax.decision_making.search_space import AbstractSearchSpace -from gpjax.decision_making.utility_functions import AbstractUtilityFunctionBuilder +from gpjax.decision_making.utility_functions import ( + AbstractUtilityFunctionBuilder, + ThompsonSampling, +) from gpjax.decision_making.utility_maximizer import AbstractUtilityMaximizer from gpjax.decision_making.utils import FunctionEvaluator from gpjax.gps import AbstractPosterior @@ -67,6 +72,9 @@ class AbstractDecisionMaker(ABC): also used to update the posteriors, using the `posterior_handlers`. Tags are used to distinguish datasets, and correspond to tags in `posterior_handlers`. key (KeyArray): JAX random key, used to generate random numbers. + batch_size (int): Number of points to query at each step of the decision making + loop. Note that `SinglePointUtilityFunction`s are only capable of generating + one point to be queried at each iteration of the decision making loop. post_ask (List[Callable]): List of functions to be executed after each ask step. post_tell (List[Callable]): List of functions to be executed after each tell step. @@ -76,9 +84,10 @@ class AbstractDecisionMaker(ABC): posterior_handlers: Dict[str, PosteriorHandler] datasets: Dict[str, Dataset] key: KeyArray + batch_size: int post_ask: List[ Callable - ] # Specific type is List[Callable[[AbstractDecisionMaker, Float[Array, ["1 D"]]], None]] but causes Beartype issues + ] # Specific type is List[Callable[[AbstractDecisionMaker, Float[Array, ["B D"]]], None]] but causes Beartype issues post_tell: List[ Callable ] # Specific type is List[Callable[[AbstractDecisionMaker], None]] but causes Beartype issues @@ -89,6 +98,15 @@ def __post_init__(self): consistent (i.e. have the same tags), and then initialise the posteriors, optimizing them using the corresponding datasets. """ + self.datasets = copy.copy( + self.datasets + ) # Ensure initial datasets passed in to DecisionMaker are not mutated from within + + if self.batch_size < 1: + raise ValueError( + f"Batch size must be greater than 0, got {self.batch_size}." + ) + # Check that posterior handlers and datasets are consistent if self.posterior_handlers.keys() != self.datasets.keys(): raise ValueError( @@ -105,9 +123,9 @@ def __post_init__(self): ) @abstractmethod - def ask(self, key: KeyArray) -> Float[Array, "1 D"]: + def ask(self, key: KeyArray) -> Float[Array, "B D"]: """ - Get the point to be queried next. + Get the point(s) to be queried next. Args: key (KeyArray): JAX PRNG key for controlling random state. @@ -222,28 +240,64 @@ class UtilityDrivenDecisionMaker(AbstractDecisionMaker): utility_function_builder: AbstractUtilityFunctionBuilder utility_maximizer: AbstractUtilityMaximizer - def ask(self, key: KeyArray) -> Float[Array, "1 D"]: + def __post_init__(self): + super().__post_init__() + if self.batch_size > 1 and not isinstance( + self.utility_function_builder, ThompsonSampling + ): + raise NotImplementedError( + "Batch size > 1 currently only supported for Thompson sampling." + ) + + def ask(self, key: KeyArray) -> Float[Array, "B D"]: """ - Get updated utility function and return the point which maximises it. This - method also stores the utility function in - `self.current_utility_function` so that it can be accessed after the ask + Get updated utility function(s) and return the point(s) which maximises it/them. This + method also stores the utility function(s) in + `self.current_utility_functions` so that they can be accessed after the ask function has been called. This is useful for non-deterministic utility - functions, which will differ between calls to `ask` due to the splitting of + functions, which may differ between calls to `ask` due to the splitting of `self.key`. + Note that in general `SinglePointUtilityFunction`s are only capable of + generating one point to be queried at each iteration of the decision making loop + (i.e. `self.batch_size` must be 1). However, Thompson sampling can be used in a + batched setting by drawing a batch of different samples from the GP posterior. + This is done by calling `build_utility_function` with different keys + sequentilly, and optimising each of these individual samples in sequence in + order to obtain `self.batch_size` points to query next. + Args: key (KeyArray): JAX PRNG key for controlling random state. Returns: - Float[Array, "1 D"]: Point to be queried next. + Float[Array, "B D"]: Point(s) to be queried next. """ - self.current_utility_function = ( - self.utility_function_builder.build_utility_function( - self.posteriors, self.datasets, key + self.current_utility_functions = [] + maximizers = [] + if isinstance(self.utility_function_builder, ThompsonSampling) or ( + (not isinstance(self.utility_function_builder, ThompsonSampling)) + and (self.batch_size == 1) + ): + # Draw 'self.batch_size' Thompson samples and optimize each of them in order to + # obtain 'self.batch_size' points to query next. + for _ in range(self.batch_size): + decision_function = ( + self.utility_function_builder.build_utility_function( + self.posteriors, self.datasets, key + ) + ) + self.current_utility_functions.append(decision_function) + + _, key = jr.split(key) + maximizer = self.utility_maximizer.maximize( + decision_function, self.search_space, key + ) + maximizers.append(maximizer) + _, key = jr.split(key) + + maximizers = jnp.concatenate(maximizers) + return maximizers + else: + raise NotImplementedError( + "Only Thompson sampling currently supports batch size > 1." ) - ) - - key, _ = jr.split(key) - return self.utility_maximizer.maximize( - self.current_utility_function, self.search_space, key - ) diff --git a/gpjax/decision_making/utility_functions/__init__.py b/gpjax/decision_making/utility_functions/__init__.py index dbf8a9577..18868949d 100644 --- a/gpjax/decision_making/utility_functions/__init__.py +++ b/gpjax/decision_making/utility_functions/__init__.py @@ -13,7 +13,9 @@ # limitations under the License. # ============================================================================== from gpjax.decision_making.utility_functions.base import ( + AbstractSinglePointUtilityFunctionBuilder, AbstractUtilityFunctionBuilder, + SinglePointUtilityFunction, UtilityFunction, ) from gpjax.decision_making.utility_functions.thompson_sampling import ThompsonSampling @@ -21,5 +23,7 @@ __all__ = [ "UtilityFunction", "AbstractUtilityFunctionBuilder", + "AbstractSinglePointUtilityFunctionBuilder", + "SinglePointUtilityFunction", "ThompsonSampling", ] diff --git a/gpjax/decision_making/utility_functions/base.py b/gpjax/decision_making/utility_functions/base.py index c06ffc9db..429c58b57 100644 --- a/gpjax/decision_making/utility_functions/base.py +++ b/gpjax/decision_making/utility_functions/base.py @@ -32,17 +32,27 @@ KeyArray, ) -UtilityFunction = Callable[[Float[Array, "N D"]], Float[Array, "N 1"]] +SinglePointUtilityFunction = Callable[[Float[Array, "N D"]], Float[Array, "N 1"]] """ -Type alias for utility functions, which take an array of points of shape $`[N, D]`$ +Type alias for utility functions which don't support batching, and instead characterise +the utility of querying a single point, rather than a batch of points. They take an array of points of shape $`[N, D]`$ and return the value of the utility function at each point in an array of shape $`[N, 1]`$. """ +UtilityFunction = SinglePointUtilityFunction +""" +Type alias for all utility functions. Currently we only support +`SinglePointUtilityFunction`s, but in future may support batched utility functions too. +Note that `UtilityFunction`s are *maximised* in order to decide which point, or batch of points, to query next. +""" + + @dataclass -class AbstractUtilityFunctionBuilder(ABC): +class AbstractSinglePointUtilityFunctionBuilder(ABC): """ - Abstract class for building utility functions. + Abstract class for building utility functions which don't support batches. As such, + they characterise the utility of querying a single point next. """ def check_objective_present( @@ -75,7 +85,7 @@ def build_utility_function( posteriors: Mapping[str, AbstractPosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> UtilityFunction: + ) -> SinglePointUtilityFunction: """ Build a `UtilityFunction` from a set of posteriors and datasets. @@ -87,7 +97,14 @@ def build_utility_function( key (KeyArray): JAX PRNG key used for random number generation. Returns: - UtilityFunction: Utility function to be *maximised* in order to + SinglePointUtilityFunction: Utility function to be *maximised* in order to decide which point to query next. """ raise NotImplementedError + + +AbstractUtilityFunctionBuilder = AbstractSinglePointUtilityFunctionBuilder +""" +Type alias for utility function builders. For now this only include single point utility +function builders, but in the future we may support batched utility function builders. +""" diff --git a/gpjax/decision_making/utility_functions/thompson_sampling.py b/gpjax/decision_making/utility_functions/thompson_sampling.py index 6ef765f5f..7367e9785 100644 --- a/gpjax/decision_making/utility_functions/thompson_sampling.py +++ b/gpjax/decision_making/utility_functions/thompson_sampling.py @@ -18,8 +18,8 @@ from gpjax.dataset import Dataset from gpjax.decision_making.utility_functions.base import ( - AbstractUtilityFunctionBuilder, - UtilityFunction, + AbstractSinglePointUtilityFunctionBuilder, + SinglePointUtilityFunction, ) from gpjax.decision_making.utils import OBJECTIVE from gpjax.gps import ConjugatePosterior @@ -27,13 +27,20 @@ @dataclass -class ThompsonSampling(AbstractUtilityFunctionBuilder): +class ThompsonSampling(AbstractSinglePointUtilityFunctionBuilder): """ Form a utility function by drawing an approximate sample from the posterior, using decoupled sampling as introduced in [Wilson et. al. (2020)](https://arxiv.org/abs/2002.09309). Note that we return the *negative* of the sample as the utility function, as utility functions are *maximised*. + Note that this is a single batch utility function, as it doesn't support classical + batching. However, Thompson sampling can be used in a batched setting by drawing a + batch of different samples from the GP posterior. This can be done by calling + `build_utility_function` with different keys, an example of which can be seen in the + `ask` method of the `UtilityDrivenDecisionMaker` class. The samples can then be + optimised sequentially. + Attributes: num_features (int): The number of random Fourier features to use when drawing the approximate sample from the posterior. Defaults to 100. @@ -52,7 +59,7 @@ def build_utility_function( posteriors: Mapping[str, ConjugatePosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> UtilityFunction: + ) -> SinglePointUtilityFunction: """ Draw an approximate sample from the posterior of the objective model and return the *negative* of this sample as a utility function, as utility functions @@ -67,10 +74,11 @@ def build_utility_function( to form the utility function. Keys in `datasets` should correspond to keys in `posteriors`. One of the datasets must correspond to the `OBJECTIVE` key. - key (KeyArray): JAX PRNG key used for random number generation. + key (KeyArray): JAX PRNG key used for random number generation. This can be + changed to draw different samples. Returns: - UtilityFunction: An appproximate sample from the objective model + SinglePointUtilityFunction: An appproximate sample from the objective model posterior to to be *maximised* in order to decide which point to query next. """ diff --git a/gpjax/decision_making/utility_maximizer.py b/gpjax/decision_making/utility_maximizer.py index ff0871f5d..633934d7f 100644 --- a/gpjax/decision_making/utility_maximizer.py +++ b/gpjax/decision_making/utility_maximizer.py @@ -26,7 +26,7 @@ AbstractSearchSpace, ContinuousSearchSpace, ) -from gpjax.decision_making.utility_functions import UtilityFunction +from gpjax.decision_making.utility_functions import SinglePointUtilityFunction from gpjax.typing import ( Array, Float, @@ -36,14 +36,15 @@ def _get_discrete_maximizer( - query_points: Float[Array, "N D"], utility_function: UtilityFunction + query_points: Float[Array, "N D"], utility_function: SinglePointUtilityFunction ) -> Float[Array, "1 D"]: """Get the point which maximises the utility function evaluated at a given set of points. Args: query_points (Float[Array, "N D"]): Set of points at which to evaluate the utility function. - utility_function (UtilityFunction): Utility function to evaluate at `query_points`. + utility_function (SinglePointUtilityFunction): Single point utility function to + be evaluated at "query_points". Returns: Float[Array, "1 D"]: Point in `query_points` which maximises the utility function. @@ -59,13 +60,13 @@ def _get_discrete_maximizer( @dataclass -class AbstractUtilityMaximizer(ABC): - """Abstract base class for utility function maximizers.""" +class AbstractSinglePointUtilityMaximizer(ABC): + """Abstract base class for single point utility function maximizers.""" @abstractmethod def maximize( self, - utility_function: UtilityFunction, + utility_function: SinglePointUtilityFunction, search_space: AbstractSearchSpace, key: KeyArray, ) -> Float[Array, "1 D"]: @@ -85,7 +86,7 @@ def maximize( @dataclass -class ContinuousUtilityMaximizer(AbstractUtilityMaximizer): +class ContinuousSinglePointUtilityMaximizer(AbstractSinglePointUtilityMaximizer): """The `ContinuousUtilityMaximizer` class is used to maximize utility functions over the continuous domain with L-BFGS-B. First we sample the utility function at `num_initial_samples` points from the search space, and then we run @@ -109,7 +110,7 @@ def __post_init__(self): def maximize( self, - utility_function: UtilityFunction, + utility_function: SinglePointUtilityFunction, search_space: ContinuousSearchSpace, key: KeyArray, ) -> Float[Array, "1 D"]: @@ -150,3 +151,10 @@ def _scalar_utility_function(x: Float[Array, "1 D"]) -> ScalarFloat: max_observed_utility_function_value = optimized_utility_function_value maximizer = optimized_point return maximizer + + +AbstractUtilityMaximizer = AbstractSinglePointUtilityMaximizer +""" +Type alias for a utility maximizer. Currently we only support single point utility +functions, but in future may support batched utility functions. +""" diff --git a/mkdocs.yml b/mkdocs.yml index 5d00248cb..7224def46 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - Stochastic sparse GPs: examples/collapsed_vi.py - Pathwise Sampling for Spatial Modelling: examples/spatial.py - Bayesian Optimisation: examples/bayesian_optimisation.py + - Decision Making: examples/decision_making.py - 📖 Guides for customisation: - Kernels: examples/constructing_new_kernels.py - Likelihoods: examples/likelihoods_guide.py diff --git a/tests/test_decision_making/test_decision_maker.py b/tests/test_decision_making/test_decision_maker.py index dad2340e1..42e5e8175 100644 --- a/tests/test_decision_making/test_decision_maker.py +++ b/tests/test_decision_making/test_decision_maker.py @@ -33,17 +33,20 @@ ContinuousSearchSpace, ) from gpjax.decision_making.test_functions import Quadratic -from gpjax.decision_making.utility_functions import AbstractUtilityFunctionBuilder +from gpjax.decision_making.utility_functions import ( + AbstractSinglePointUtilityFunctionBuilder, + ThompsonSampling, +) from gpjax.decision_making.utility_maximizer import ( - AbstractUtilityMaximizer, - ContinuousUtilityMaximizer, + AbstractSinglePointUtilityMaximizer, + ContinuousSinglePointUtilityMaximizer, ) from gpjax.decision_making.utils import ( OBJECTIVE, build_function_evaluator, ) from gpjax.typing import KeyArray -from tests.test_decision_making.utils import QuadraticUtilityFunctionBuilder +from tests.test_decision_making.utils import QuadraticSinglePointUtilityFunctionBuilder CONSTRAINT = "CONSTRAINT" @@ -75,13 +78,20 @@ def posterior_handler() -> PosteriorHandler: @pytest.fixture -def utility_function_builder() -> AbstractUtilityFunctionBuilder: - return QuadraticUtilityFunctionBuilder() +def utility_function_builder() -> AbstractSinglePointUtilityFunctionBuilder: + return QuadraticSinglePointUtilityFunctionBuilder() + + +@pytest.fixture +def thompson_sampling_utility_function_builder() -> ThompsonSampling: + return ThompsonSampling(num_features=100) @pytest.fixture -def utility_maximizer() -> AbstractUtilityMaximizer: - return ContinuousUtilityMaximizer(num_initial_samples=1000, num_restarts=1) +def utility_maximizer() -> AbstractSinglePointUtilityMaximizer: + return ContinuousSinglePointUtilityMaximizer( + num_initial_samples=1000, num_restarts=1 + ) def get_dataset(num_points: int, key: KeyArray) -> Dataset: @@ -95,14 +105,70 @@ def test_abstract_decision_maker_raises_error(): AbstractDecisionMaker() +@pytest.mark.parametrize("batch_size", [0, -1, -10]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_invalid_batch_size_raises_error( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, + batch_size: int, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = {"OBJECTIVE": objective_dataset} + with pytest.raises(ValueError): + UtilityDrivenDecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, + key=key, + post_ask=[], + post_tell=[], + batch_size=batch_size, + ) + + +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_non_thompson_sampling_non_one_batch_size_raises_error( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = {"OBJECTIVE": objective_dataset} + with pytest.raises(NotImplementedError): + UtilityDrivenDecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + utility_function_builder=utility_function_builder, + utility_maximizer=utility_maximizer, + key=key, + post_ask=[], + post_tell=[], + batch_size=2, + ) + + @pytest.mark.filterwarnings( "ignore::UserWarning" ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_invalid_tags_raises_error( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler} @@ -118,6 +184,7 @@ def test_invalid_tags_raises_error( key=key, post_ask=[], post_tell=[], + batch_size=1, ) @@ -127,8 +194,8 @@ def test_invalid_tags_raises_error( def test_initialisation_optimizes_posterior_hyperparameters( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} @@ -144,6 +211,7 @@ def test_initialisation_optimizes_posterior_hyperparameters( key=key, post_ask=[], post_tell=[], + batch_size=1, ) # Assert kernel hyperparameters get changed from their initial values assert decision_maker.posteriors[OBJECTIVE].prior.kernel.lengthscale != jnp.array( @@ -170,8 +238,8 @@ def test_initialisation_optimizes_posterior_hyperparameters( def test_decision_maker_ask( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler} @@ -186,12 +254,51 @@ def test_decision_maker_ask( key=key, post_ask=[], post_tell=[], + batch_size=1, ) initial_decision_maker_key = decision_maker.key query_point = decision_maker.ask(key=key) assert query_point.shape == (1, 1) assert jnp.allclose(query_point, jnp.array([[0.5]]), atol=1e-5) - assert decision_maker.current_utility_function is not None + assert len(decision_maker.current_utility_functions) == 1 + assert ( + decision_maker.key == initial_decision_maker_key + ).all() # Ensure decision maker key is unchanged + + +@pytest.mark.parametrize("batch_size", [1, 2, 5]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_ask_multi_batch_ts( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + thompson_sampling_utility_function_builder: ThompsonSampling, + utility_maximizer: AbstractSinglePointUtilityMaximizer, + batch_size: int, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + datasets = {"OBJECTIVE": objective_dataset} + decision_maker = UtilityDrivenDecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=datasets, + utility_function_builder=thompson_sampling_utility_function_builder, + utility_maximizer=utility_maximizer, + key=key, + post_ask=[], + post_tell=[], + batch_size=batch_size, + ) + initial_decision_maker_key = decision_maker.key + query_points = decision_maker.ask(key=key) + assert query_points.shape == (batch_size, 1) + assert ( + len(jnp.unique(query_points)) == batch_size + ) # Ensure we aren't drawing the same Thompson sample each time + assert len(decision_maker.current_utility_functions) == batch_size assert ( decision_maker.key == initial_decision_maker_key ).all() # Ensure decision maker key is unchanged @@ -203,15 +310,15 @@ def test_decision_maker_ask( def test_decision_maker_tell_with_inconsistent_observations_raises_error( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) initial_constraint_dataset = get_dataset(num_points=5, key=jr.PRNGKey(10)) datasets = { - "OBJECTIVE": initial_objective_dataset, + OBJECTIVE: initial_objective_dataset, CONSTRAINT: initial_constraint_dataset, } decision_maker = UtilityDrivenDecisionMaker( @@ -223,6 +330,7 @@ def test_decision_maker_tell_with_inconsistent_observations_raises_error( key=key, post_ask=[], post_tell=[], + batch_size=1, ) mock_objective_observation = get_dataset(num_points=1, key=jr.PRNGKey(1)) mock_constraint_observation = get_dataset(num_points=1, key=jr.PRNGKey(2)) @@ -240,8 +348,8 @@ def test_decision_maker_tell_with_inconsistent_observations_raises_error( def test_decision_maker_tell_updates_datasets_and_models( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler, CONSTRAINT: posterior_handler} @@ -260,6 +368,7 @@ def test_decision_maker_tell_updates_datasets_and_models( key=key, post_ask=[], post_tell=[], + batch_size=1, ) initial_decision_maker_key = decision_maker.key initial_objective_posterior = decision_maker.posteriors[OBJECTIVE] @@ -303,25 +412,26 @@ def test_decision_maker_tell_updates_datasets_and_models( def test_decision_maker_run( search_space: AbstractSearchSpace, posterior_handler: PosteriorHandler, - utility_function_builder: AbstractUtilityFunctionBuilder, - utility_maximizer: AbstractUtilityMaximizer, + utility_function_builder: AbstractSinglePointUtilityFunctionBuilder, + utility_maximizer: AbstractSinglePointUtilityMaximizer, n_steps: int, ): key = jr.PRNGKey(42) posterior_handlers = {OBJECTIVE: posterior_handler} initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) - datasets = { + initial_datasets = { "OBJECTIVE": initial_objective_dataset, } decision_maker = UtilityDrivenDecisionMaker( search_space=search_space, posterior_handlers=posterior_handlers, - datasets=datasets, + datasets=initial_datasets, utility_function_builder=utility_function_builder, utility_maximizer=utility_maximizer, key=key, post_ask=[], post_tell=[], + batch_size=1, ) initial_decision_maker_key = decision_maker.key black_box_fn = Quadratic() @@ -331,6 +441,7 @@ def test_decision_maker_run( query_datasets = decision_maker.run( n_steps=n_steps, black_box_function_evaluator=black_box_function_evaluator ) + assert initial_datasets[OBJECTIVE].n == 5 assert query_datasets[OBJECTIVE].n == 5 + n_steps assert ( jnp.abs(query_datasets[OBJECTIVE].X[-n_steps:] - jnp.array([[0.5]])) < 1e-5 @@ -338,3 +449,50 @@ def test_decision_maker_run( assert ( decision_maker.key != initial_decision_maker_key ).all() # Ensure decision maker key gets updated + + +@pytest.mark.parametrize("n_steps", [1, 3]) +@pytest.mark.parametrize("batch_size", [1, 3]) +@pytest.mark.filterwarnings( + "ignore::UserWarning" +) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort +def test_decision_maker_run_ts( + search_space: AbstractSearchSpace, + posterior_handler: PosteriorHandler, + thompson_sampling_utility_function_builder: ThompsonSampling, + utility_maximizer: AbstractSinglePointUtilityMaximizer, + n_steps: int, + batch_size: int, +): + key = jr.PRNGKey(42) + posterior_handlers = {OBJECTIVE: posterior_handler} + initial_objective_dataset = get_dataset(num_points=5, key=jr.PRNGKey(42)) + initial_datasets = { + "OBJECTIVE": initial_objective_dataset, + } + decision_maker = UtilityDrivenDecisionMaker( + search_space=search_space, + posterior_handlers=posterior_handlers, + datasets=initial_datasets, + utility_function_builder=thompson_sampling_utility_function_builder, + utility_maximizer=utility_maximizer, + key=key, + post_ask=[], + post_tell=[], + batch_size=batch_size, + ) + initial_decision_maker_key = decision_maker.key + black_box_fn = Quadratic() + black_box_function_evaluator = build_function_evaluator( + {OBJECTIVE: black_box_fn.evaluate} + ) + query_datasets = decision_maker.run( + n_steps=n_steps, black_box_function_evaluator=black_box_function_evaluator + ) + assert initial_datasets[OBJECTIVE].n == 5 + assert ( + query_datasets[OBJECTIVE].n == 5 + n_steps * batch_size + ) # Ensure we're getting the correct number of points + assert ( + decision_maker.key != initial_decision_maker_key + ).all() # Ensure decision maker key gets updated diff --git a/tests/test_decision_making/test_utility_maximizer.py b/tests/test_decision_making/test_utility_maximizer.py index 980add289..13b7287c8 100644 --- a/tests/test_decision_making/test_utility_maximizer.py +++ b/tests/test_decision_making/test_utility_maximizer.py @@ -27,16 +27,16 @@ Quadratic, ) from gpjax.decision_making.utility_maximizer import ( - AbstractUtilityMaximizer, - ContinuousUtilityMaximizer, + AbstractSinglePointUtilityMaximizer, + ContinuousSinglePointUtilityMaximizer, _get_discrete_maximizer, ) from gpjax.typing import KeyArray -def test_abstract_utility_maximizer(): +def test_abstract_single_batch_utility_maximizer(): with pytest.raises(TypeError): - AbstractUtilityMaximizer() + AbstractSinglePointUtilityMaximizer() @pytest.mark.parametrize( @@ -67,7 +67,7 @@ def test_continuous_maximizer_raises_error_with_erroneous_num_initial_samples( num_initial_samples: int, ): with pytest.raises(ValueError): - ContinuousUtilityMaximizer( + ContinuousSinglePointUtilityMaximizer( num_initial_samples=num_initial_samples, num_restarts=1 ) @@ -77,7 +77,9 @@ def test_continuous_maximizer_raises_error_with_erroneous_num_restarts( num_restarts: int, ): with pytest.raises(ValueError): - ContinuousUtilityMaximizer(num_initial_samples=1, num_restarts=num_restarts) + ContinuousSinglePointUtilityMaximizer( + num_initial_samples=1, num_restarts=num_restarts + ) @pytest.mark.parametrize( @@ -95,10 +97,10 @@ def test_continous_maximizer_returns_same_point_with_same_key( key: KeyArray, num_restarts: int, ): - continuous_maximizer_one = ContinuousUtilityMaximizer( + continuous_maximizer_one = ContinuousSinglePointUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) - continuous_maximizer_two = ContinuousUtilityMaximizer( + continuous_maximizer_two = ContinuousSinglePointUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) utility_function = lambda x: -1.0 * test_function.evaluate(x) @@ -137,7 +139,7 @@ def test_continuous_maximizer_finds_correct_point( key: KeyArray, num_restarts: int, ): - continuous_utility_maximizer = ContinuousUtilityMaximizer( + continuous_utility_maximizer = ContinuousSinglePointUtilityMaximizer( num_initial_samples=1000, num_restarts=num_restarts ) utility_function = lambda x: -1.0 * test_function.evaluate(x) @@ -159,7 +161,7 @@ def test_continuous_maximizer_finds_correct_point( ) # Sampling with tfp causes JAX to raise a UserWarning due to some internal logic around jnp.argsort def test_continuous_maximizer_jaxopt_component(key: KeyArray, num_restarts: int): quadratic = Quadratic() - continuous_utility_maximizer = ContinuousUtilityMaximizer( + continuous_utility_maximizer = ContinuousSinglePointUtilityMaximizer( num_initial_samples=1, # Force JaxOpt L-GFBS-B to do the heavy lifting num_restarts=num_restarts, ) diff --git a/tests/test_decision_making/utils.py b/tests/test_decision_making/utils.py index 90ad2d75a..4ea3e9dc3 100644 --- a/tests/test_decision_making/utils.py +++ b/tests/test_decision_making/utils.py @@ -18,19 +18,21 @@ from gpjax.dataset import Dataset from gpjax.decision_making.test_functions import Quadratic from gpjax.decision_making.utility_functions import ( - AbstractUtilityFunctionBuilder, - UtilityFunction, + AbstractSinglePointUtilityFunctionBuilder, + SinglePointUtilityFunction, ) from gpjax.gps import ConjugatePosterior from gpjax.typing import KeyArray -class QuadraticUtilityFunctionBuilder(AbstractUtilityFunctionBuilder): +class QuadraticSinglePointUtilityFunctionBuilder( + AbstractSinglePointUtilityFunctionBuilder +): """ Dummy utility function builder for testing purposes, which returns the negative of the value of a quadratic test function at the input points. This is because utility functions are *maximised*, and we wish to *minimise* the quadratic test - function. + function. Note that this is a `SinglePointUtilityFunctionBuilder`. """ def build_utility_function( @@ -38,7 +40,7 @@ def build_utility_function( posteriors: Mapping[str, ConjugatePosterior], datasets: Mapping[str, Dataset], key: KeyArray, - ) -> UtilityFunction: + ) -> SinglePointUtilityFunction: test_function = Quadratic() return lambda x: -1.0 * test_function.evaluate( x From 68f9cc53fe04dca5b0e28779ba1e1922cef7b40d Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 18:40:59 +0100 Subject: [PATCH 70/76] Bump planetary-computer. --- poetry.lock | 57 ++++++++++++++++++++++++++++++++------------------ pyproject.toml | 2 +- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index b386e35c6..813b9417f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -168,7 +168,7 @@ frozenlist = ">=1.1.0" name = "annotated-types" version = "0.5.0" description = "Reusable constraint types to use with typing.Annotated" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -462,7 +462,7 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -563,7 +563,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -668,7 +668,7 @@ typing-extensions = ">=4.2.0" name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1584,7 +1584,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3395,7 +3395,7 @@ testing = ["flax", "pytest", "pytest-xdist"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3616,21 +3616,23 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "planetary-computer" -version = "0.5.1" +version = "1.0.0" description = "Planetary Computer SDK for Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "planetary-computer-0.5.1.tar.gz", hash = "sha256:a46de4a6bab359a5b691f2059f5dbe842c92b45390b5f1ab465bdf2819008d35"}, - {file = "planetary_computer-0.5.1-py3-none-any.whl", hash = "sha256:87cd7b89a8df33b71aab3a05b390ecedd3830ece1bb3ad33725019db30c9683f"}, + {file = "planetary-computer-1.0.0.tar.gz", hash = "sha256:5958a8e1d8ba1aafc7ac45878df2d7d03405806ae31ed2e675333faebca960cc"}, + {file = "planetary_computer-1.0.0-py3-none-any.whl", hash = "sha256:7af5839f9346c1d23d53fff4e80e955db18a2d81992877816e22dcbc2f90c40d"}, ] [package.dependencies] click = ">=7.1" -pydantic = {version = ">=1.7.3", extras = ["dotenv"]} +packaging = "*" +pydantic = ">=1.7.3" pystac = ">=1.0.0" pystac-client = ">=0.2.0" +python-dotenv = "*" pytz = ">=2020.5" requests = ">=2.25.1" @@ -3830,7 +3832,7 @@ files = [ name = "pydantic" version = "2.3.0" description = "Data validation using Python type hints" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3850,7 +3852,7 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.6.3" description = "" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4143,7 +4145,7 @@ test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] name = "pystac" version = "1.8.3" description = "Python library for working with the SpatioTemporal Asset Catalog (STAC) specification" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4167,7 +4169,7 @@ validation = ["jsonschema (>=4.0.1,<4.18)"] name = "pystac-client" version = "0.6.1" description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4266,7 +4268,7 @@ testing = ["filelock"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "dev" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -4277,6 +4279,21 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pytkdocs" version = "0.16.1" @@ -4296,7 +4313,7 @@ numpy-style = ["docstring_parser (>=0.7)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "dev" +category = "main" optional = false python-versions = "*" files = [ @@ -4679,7 +4696,7 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5415,7 +5432,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5813,4 +5830,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "95048d017009d7fafa176580db39b5b348e1dded982777edc6771ceb8e0c6135" +content-hash = "6e21cbf7e34230b2eff4a6ec911947c1504dc96620f6401f7c4b1b91d85a79ec" diff --git a/pyproject.toml b/pyproject.toml index 6794e2091..4da19cfed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ jax = ">=0.4.10" jaxlib = ">=0.4.10" orbax-checkpoint = ">=0.2.3" cola-ml = "^0.0.1" +planetary-computer = ">=1.0.0" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" @@ -73,7 +74,6 @@ scikit-learn = "^1.2.2" flax = "^0.6.8" xarray = "^2023.1" pystac-client = "^0.6.1" -planetary-computer = "^0.5.1" fsspec = "^2023.4.0" aiohttp = "^3.8.4" rioxarray = "^0.13" From da3cd57495aa13791140e7a0ac4c093dbae285b8 Mon Sep 17 00:00:00 2001 From: Daniel Dodd Date: Wed, 6 Sep 2023 19:11:48 +0100 Subject: [PATCH 71/76] Add planetary-computer back to dev. --- poetry.lock | 34 +++++++++++++++++----------------- pyproject.toml | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 813b9417f..d01a47e68 100644 --- a/poetry.lock +++ b/poetry.lock @@ -168,7 +168,7 @@ frozenlist = ">=1.1.0" name = "annotated-types" version = "0.5.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -462,7 +462,7 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -563,7 +563,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -668,7 +668,7 @@ typing-extensions = ">=4.2.0" name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1584,7 +1584,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -3395,7 +3395,7 @@ testing = ["flax", "pytest", "pytest-xdist"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3618,7 +3618,7 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "planetary-computer" version = "1.0.0" description = "Planetary Computer SDK for Python" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3832,7 +3832,7 @@ files = [ name = "pydantic" version = "2.3.0" description = "Data validation using Python type hints" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3852,7 +3852,7 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.6.3" description = "" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4145,7 +4145,7 @@ test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] name = "pystac" version = "1.8.3" description = "Python library for working with the SpatioTemporal Asset Catalog (STAC) specification" -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4169,7 +4169,7 @@ validation = ["jsonschema (>=4.0.1,<4.18)"] name = "pystac-client" version = "0.6.1" description = "Python library for working with Spatiotemporal Asset Catalog (STAC)." -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4268,7 +4268,7 @@ testing = ["filelock"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -4283,7 +4283,7 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4313,7 +4313,7 @@ numpy-style = ["docstring_parser (>=0.7)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -4696,7 +4696,7 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5432,7 +5432,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5830,4 +5830,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "6e21cbf7e34230b2eff4a6ec911947c1504dc96620f6401f7c4b1b91d85a79ec" +content-hash = "5579512ea30793a8d3ea7fe9e486e2635226caa0bf5415b173f650751c8b3016" diff --git a/pyproject.toml b/pyproject.toml index 4da19cfed..cb79ec675 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ jax = ">=0.4.10" jaxlib = ">=0.4.10" orbax-checkpoint = ">=0.2.3" cola-ml = "^0.0.1" -planetary-computer = ">=1.0.0" [tool.poetry.group.test.dependencies] pytest = "^7.2.2" @@ -74,6 +73,7 @@ scikit-learn = "^1.2.2" flax = "^0.6.8" xarray = "^2023.1" pystac-client = "^0.6.1" +planetary-computer = "^1.0.0" fsspec = "^2023.4.0" aiohttp = "^3.8.4" rioxarray = "^0.13" From b73e3735fe9ba50a2b4beb3d098d0ecd9408366d Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Thu, 7 Sep 2023 15:40:22 +0100 Subject: [PATCH 72/76] punctuation, fixed links and fixed plots --- docs/examples/oceanmodelling.py | 94 ++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index c9344d0bb..ed62ea8fe 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -2,10 +2,10 @@ # # Gaussian Processes for Vector Fields and Ocean Current Modelling # # In this notebook, we use Gaussian processes to learn vector valued functions. We will be -# recreating the results by [Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf) by an -# application to real world ocean surface velocity data, collected via surface drifters. +# recreating the results by [Berlinghieri et al. (2023)](https://arxiv.org/pdf/2302.10364.pdf) by an +# application to real-world ocean surface velocity data, collected via surface drifters. # -# Surface drifters are measurement devices that measure the dynamics and circulation patterns of the world's oceans. Studying and predicting ocean currents are important to climate research, for example forecasting and predicting oil spills, oceanographic surveying of eddies and upwelling, or providing information on the distribution of biomass in ecosystems. We will be using the [Gulf Drifters Open dataset](https://zenodo.org/record/4421585), which contains all publicly available surface drifter trajectories from the Gulf of Mexico spanning 28 years. +# Surface drifters are measurement devices that measure the dynamics and circulation patterns of the world's oceans. Studying and predicting ocean currents are important to climate research, for example, forecasting and predicting oil spills, oceanographic surveying of eddies and upwelling, or providing information on the distribution of biomass in ecosystems. We will be using the [Gulf Drifters Open dataset](https://zenodo.org/record/4421585), which contains all publicly available surface drifter trajectories from the Gulf of Mexico spanning 28 years. # %% from jax.config import config @@ -39,7 +39,7 @@ # %% [markdown] -# ## Data Loading and problem setting +# ## Data loading and preprocessing # The real dataset has been binned into an $N=34\times16$ grid, equally spaced over the longitude-latitude interval $[-90.8,-83.8] \times [24.0,27.5]$. Each bin has a size $\approx 0.21\times0.21$, and contains the average velocity across all measurements that fall inside it. # # We will call this binned ocean data the ground truth, and label it with the vector field @@ -48,7 +48,7 @@ # $$ # where $\mathbf{x} = (x^{(0)}$,$x^{(1)})^\text{T}$, with a vector basis in the standard Cartesian directions (dimensions will be indicated by superscripts). # -# We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_i$ is the 2 dimensional velocity vector at the $i$th location, $\mathbf{x}_i$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). +# We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_{,i$ is the 2-dimensional velocity vector at the $i$-th location, $\mathbf{x}_{0,i}$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). # @@ -68,24 +68,24 @@ def prepare_data(df): # loading in data gulf_data_train = pd.read_csv( - "https://raw.githubusercontent.com/JaxGaussianProcesses/gpjaxstatic/main/data/gulfdata_train.csv" + "https://raw.githubusercontent.com/JaxGaussianProcesses/static/main/data/gulfdata_train.csv" ) gulf_data_test = pd.read_csv( - "https://raw.githubusercontent.com/JaxGaussianProcesses/gpjaxstatic/main/data/gulfdata_test.csv" + "https://raw.githubusercontent.com/JaxGaussianProcesses/static/main/data/gulfdata_test.csv" ) pos_test, vel_test, shape = prepare_data(gulf_data_test) pos_train, vel_train = prepare_data(gulf_data_train) -fig, ax = plt.subplots(1, 1) +fig, ax = plt.subplots(1, 1, figsize=(6, 3)) ax.quiver( pos_test[0], pos_test[1], vel_test[0], vel_test[1], color=colors[0], - label="$D_0$", + label="Ocean Current", angles="xy", scale=10, ) @@ -96,16 +96,27 @@ def prepare_data(df): vel_train[1], color=colors[1], alpha=0.7, - label="$D_T$", + label="Drifter", angles="xy", scale=10, ) -ax.legend() + +ax.set( + xlabel="Longitude", + ylabel="Latitude", +) +ax.legend( + framealpha=0.0, + ncols=2, + fontsize="medium", + bbox_to_anchor=(0.5, -0.3), + loc="lower center", +) plt.show() # %% [markdown] # ## Problem Setting -# Our aim is to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth $D_0$. Note that $D_0$ is not passed into any functions used by GPJax, and is only used to compare against the two GP models at the end of the notebook. +# We aim to obtain estimates for $\mathbf{F}$ at the set of points $\left\{ \mathbf{x}_{0,i} \right\}_{i=1}^N$ using Gaussian processes, followed by a comparison of the latent model to the ground truth $D_0$. Note that $D_0$ is not passed into any functions used by GPJax, and is only used to compare against the two GP models at the end of the notebook. # # Since $\mathbf{F}$ is a vector-valued function, we require GPs that can directly learn vector-valued functions[1](#fn1). To implement this in GPJax, the problem can be changed to learn a scalar-valued function by 'massaging' the data into a $2N\times2N$ problem, such that each dimension of our GP is associated with a *component* of $\mathbf{y}_{T,i}$. # @@ -115,7 +126,7 @@ def prepare_data(df): # \mathbf{y} = \mathbf{F}(\mathbf{x}) = \left(\begin{array}{l} # f^{(0)}\left(\mathbf{x}\right) \\ # f^{(1)}\left(\mathbf{x}\right) -# \end{array}\right) +# \end{array}\right), # $$ # # where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. @@ -128,7 +139,8 @@ def prepare_data(df): # # We have increased the input dimension by 1, from the 2D $\mathbf{x}$ to the 3D $\mathbf{X} = \left(\mathbf{x}, 0\right)$ or $\mathbf{X} = \left(\mathbf{x}, 1\right)$. # -# By choosing the value of the third dimension, 0 or 1, we may now incorporate this information into computation of the kernel. +# By choosing the value of the third dimension, 0 or 1, we may now incorporate this +# information into the computation of the kernel. # We therefore make new 3D datasets $D_{T,3D} = \left\{\left( \mathbf{X}_{T,i},\mathbf{Y}_{T,i} \right) \right\} _{i=0}^{2N_T}$ and $D_{0,3D} = \left\{\left( \mathbf{X}_{0,i},\mathbf{Y}_{0,i} \right) \right\} _{i=0}^{2N}$ that incorporates this new labelling, such that for each dataset (indicated by the subscript $D = 0$ or $D=T$), # # $$ @@ -168,11 +180,13 @@ def dataset_3d(pos, vel): # %% [markdown] -# ## Velocity (Dimension) Decomposition -# Having labelled the data, we are now in a position to use GPJax to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly onto the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, +# ## Velocity (dimension) decomposition +# Having labelled the data, we are now in a position to use GPJax to learn the function $g$, and hence $\mathbf{F}$. A naive approach to the problem is to apply a GP prior directly to the velocities of each dimension independently, which is called the *velocity* GP. For our prior, we choose an isotropic mean 0 over all dimensions of the GP, and a piecewise kernel that depends on the $z$ labels of the inputs, such that for two inputs $\mathbf{X} = \left( \mathbf{x}, z \right )$ and $\mathbf{X}^\prime = \left( \mathbf{x}^\prime, z^\prime \right )$, # # $$ -# k_{\text{vel}} \left(\mathbf{X}, \mathbf{X}^{\prime}\right)= \begin{cases}k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right) & \text { if } z=z^{\prime} \\ 0 & \text { if } z \neq z^{\prime}\end{cases} +# k_{\text{vel}} \left(\mathbf{X}, \mathbf{X}^{\prime}\right)= +# \begin{cases}k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right) & \text { if } +# z=z^{\prime} \\ 0 & \text { if } z \neq z^{\prime}, \end{cases} # $$ # # where $k^{(z)}\left(\mathbf{x}, \mathbf{x}^{\prime}\right)$ are the user chosen kernels for each dimension. What this means is that there are no correlations between the $x^{(0)}$ and $x^{(1)}$ dimensions for all choices $\mathbf{X}$ and $\mathbf{X}^{\prime}$, since there are no off-diagonal elements in the Gram matrix populated by this choice. @@ -203,8 +217,8 @@ def __call__( # %% [markdown] -# ### GPJax Implementation -# Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean and 0 observation noise. We choose a Gaussian marginal log likelihood (MLL). +# ### GPJax implementation +# Next, we define the model in GPJax. The prior is defined using $k_{\text{vel}}\left(\mathbf{X}, \mathbf{X}^\prime \right)$ and 0 mean and 0 observation noise. We choose a Gaussian marginal log-likelihood (MLL). # @@ -225,12 +239,12 @@ def initialise_gp(kernel, mean, dataset): # %% [markdown] -# With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the marginal log likelihood using `optax`. We also plot its value at each step to visually confirm that we have found the minimum. See the [introduction to Gaussian Processes](https://docs.jaxgaussianprocesses.com/examples/intro_to_gps/) notebook for more information on optimising the MLL. +# With a model now defined, we can proceed to optimise the hyperparameters of our likelihood over $D_0$. This is done by minimising the MLL using `optax`. We also plot its value at each step to visually confirm that we have found the minimum. See the [introduction to Gaussian Processes](https://docs.jaxgaussianprocesses.com/examples/intro_to_gps/) notebook for more information on optimising the MLL. # %% def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): - # define the Marginal Log likelihood using dataset_train + # define the MLL using dataset_train objective = gpx.objectives.ConjugateMLL(negative=True) # Optimise to minimise the MLL optimiser = ox.adam(learning_rate=0.1) @@ -247,7 +261,7 @@ def optimise_mll(posterior, dataset, NIters=1000, key=key, plot_history=True): if plot_history: fig, ax = plt.subplots(1, 1) ax.plot(history, color=colors[1]) - ax.set(xlabel="Training iteration", ylabel="Negative marginal log likelihood") + ax.set(xlabel="Training iteration", ylabel="Negative MLL") return opt_posterior @@ -277,7 +291,7 @@ def latent_distribution(opt_posterior, pos_3d, dataset_train): # %% [markdown] -# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $\mathbf{R}(\mathbf{x}_i) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i) $, as well as $\left|\left|\mathbf{R}(\mathbf{x}_i)\right|\right|$. +# We now replot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $\mathbf{R}(\mathbf{x}_{0,i}) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i}) $, as well as $\left|\left|\mathbf{R}(\mathbf{x}_{0,i})\right|\right|$. # %% @@ -318,7 +332,7 @@ def plot_fields( X = dataset_ground_truth.X[:, 0][::2] Y = dataset_ground_truth.X[:, 1][::2] # make figure - fig, ax = plt.subplots(1, 3, figsize=(12.0, 2.7), sharey=True) + fig, ax = plt.subplots(1, 3, figsize=(12.0, 3.0), sharey=True) # ground truth plot_vector_field( @@ -337,7 +351,7 @@ def plot_fields( angles="xy", scale=scale, ) - prepare_ax(ax[0], X, Y, "Ground Truth") + prepare_ax(ax[0], X, Y, "Ground Truth", xlabel="Longitude") # Latent estimate of vector field F plot_vector_field(ax[1], dataset_latent, color=colors[0], angles="xy", scale=scale) @@ -364,7 +378,13 @@ def plot_fields( prepare_ax(ax[2], X, Y, "Residuals", xlabel="Longitude") fig.colorbar(im, fraction=0.027, pad=0.04, orientation="vertical") - fig.legend(loc="lower center", framealpha=0.0, ncols=3, fontsize="medium") + fig.legend( + framealpha=0.0, + ncols=2, + fontsize="medium", + bbox_to_anchor=(0.5, -0.03), + loc="lower center", + ) plt.show() @@ -372,11 +392,11 @@ def plot_fields( # %% [markdown] -# From the Latent Estimate we can see the velocity GP struggles to reconstruct features of the ground truth. This is because our construction of the kernel placed an independent prior on each physical dimension, which cannot be assumed. Therefore, we need a different approach that can implicitly incorporate this dependence at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. +# From the latent estimate we can see the velocity GP struggles to reconstruct features of the ground truth. This is because our construction of the kernel placed an independent prior on each physical dimension, which cannot be assumed. Therefore, we need a different approach that can implicitly incorporate this dependence at a fundamental level. To achieve this we will require a *Helmholtz Decomposition*. # %% [markdown] -# ## Helmholtz Decomposition +# ## Helmholtz decomposition # In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)) such that # $$ # \mathbf{F}=\operatorname{grad} \Phi+\operatorname{rot} \Psi, @@ -413,7 +433,7 @@ def plot_fields( # Note that we have operated $\dfrac{\partial}{\partial x^{(z)}}$, *not* $\dfrac{\partial}{\partial \left(x^\prime \right)^{(z)}}$, as the boxed equation suggests. This is not an issue if we choose stationary kernels $k(\mathbf{x}, \mathbf{x}^{\prime}) = k(\mathbf{x} - \mathbf{x}^{\prime})$ , as the partial derivatives with respect to the components have the following exchange symmetry: # # $$ -# \frac{\partial}{\partial x^{(z)}} = - \frac{\partial}{\partial \left( x^\prime \right)^{(z)}} +# \frac{\partial}{\partial x^{(z)}} = - \frac{\partial}{\partial \left( x^\prime \right)^{(z)}}, # $$ # # for either $z$. @@ -444,8 +464,8 @@ def __call__( # %% [markdown] -# ### GPJax Implementation -# We repeat the exact same steps as with the velocity GP model, but replacing `VelocityKernel` with `HelmholtzKernel`. +# ### GPJax iImplementation +# We repeat the same steps as with the velocity GP model, replacing `VelocityKernel` with `HelmholtzKernel`. # %% # Redefine Gaussian process with Helmholtz kernel @@ -457,7 +477,7 @@ def __call__( # %% [markdown] # ### Comparison -# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x_i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_i) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_i)$ and $\left|\left|R(\mathbf{x}_i) \right|\right|$. +# We again plot the ground truth (testing data) $D_0$, the predicted latent vector field $\mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$, and a heatmap of the residuals at each location $R(\mathbf{x}_{0,i}) = \mathbf{y}_{0,i} - \mathbf{F}_{\text{latent}}(\mathbf{x}_{0,i})$ and $\left|\left|R(\mathbf{x}_{0,i}) \right|\right|$. # %% # obtain latent distribution, extract x and y values over g @@ -469,12 +489,12 @@ def __call__( plot_fields(dataset_ground_truth, dataset_train, dataset_latent_helmholtz) # %% [markdown] -# Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). +# Visually, the Helmholtz model performs better than the velocity model, preserving the local structure of the $\mathbf{F}$. Since we placed priors on $\Phi$ and $\Psi$, the construction of $\mathbf{F}$ allows for correlations between the dimensions (non-zero off-diagonal elements in the Gram matrix populated by $k_\text{Helm}\left(\mathbf{X},\mathbf{X}^{\prime}\right)$ ). # %% [markdown] -# ## Negative Log Predictive Densities -# Lastly, we directly compare the velocity and Hemlholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data. +# ## Negative log predictive densities +# Lastly, we directly compare the velocity and Helmholtz models by computing the [negative log predictive densities](https://en.wikipedia.org/wiki/Negative_log_predictive_density) for each model. This is a quantitative metric that measures the probability of the ground truth given the data. # # $$ # \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right), @@ -502,8 +522,8 @@ def nlpd(mean, std, vel_test): # %% [markdown] # # ## Footnote -# Kernels for vector valued functions have been studied in the literature, see [Alvarez et. al, (2012)](https://doi.org/10.48550/arXiv.1106.6251) -# ## System Configuration +# Kernels for vector-valued functions have been studied in the literature, see [Alvarez et al. (2012)](https://doi.org/10.48550/arXiv.1106.6251) +# ## System configuration # %% # %reload_ext watermark # %watermark -n -u -v -iv -w -a 'Ivan Shalashilin' From ae862574203a1ab12c0dbed1013287556e91a68e Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Thu, 7 Sep 2023 16:31:29 +0100 Subject: [PATCH 73/76] added notebook to .yml --- docs/examples/oceanmodelling.py | 2 +- mkdocs.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index ed62ea8fe..107e3f12b 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -1,7 +1,7 @@ # %% [markdown] # # Gaussian Processes for Vector Fields and Ocean Current Modelling # -# In this notebook, we use Gaussian processes to learn vector valued functions. We will be +# In this notebook, we use Gaussian processes to learn vector-valued functions. We will be # recreating the results by [Berlinghieri et al. (2023)](https://arxiv.org/pdf/2302.10364.pdf) by an # application to real-world ocean surface velocity data, collected via surface drifters. # diff --git a/mkdocs.yml b/mkdocs.yml index 5d00248cb..138850262 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - Stochastic sparse GPs: examples/collapsed_vi.py - Pathwise Sampling for Spatial Modelling: examples/spatial.py - Bayesian Optimisation: examples/bayesian_optimisation.py + - Multi-output GPs for Ocean Modelling: examples/oceanmodelling.py - 📖 Guides for customisation: - Kernels: examples/constructing_new_kernels.py - Likelihoods: examples/likelihoods_guide.py From 8da98ce04730f47d65e2d65f15c1e1c39a7bc747 Mon Sep 17 00:00:00 2001 From: Thomas-Christie Date: Fri, 8 Sep 2023 10:09:39 +0100 Subject: [PATCH 74/76] Clarify batching in `ask` logic of decision maker --- gpjax/decision_making/decision_maker.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gpjax/decision_making/decision_maker.py b/gpjax/decision_making/decision_maker.py index ca4709dac..a8d2b8ef7 100644 --- a/gpjax/decision_making/decision_maker.py +++ b/gpjax/decision_making/decision_maker.py @@ -274,6 +274,8 @@ def ask(self, key: KeyArray) -> Float[Array, "B D"]: """ self.current_utility_functions = [] maximizers = [] + # We currently only allow Thompson sampling to be run with batch size > 1. More + # batched utility functions may be added in the future. if isinstance(self.utility_function_builder, ThompsonSampling) or ( (not isinstance(self.utility_function_builder, ThompsonSampling)) and (self.batch_size == 1) From d24daf4d258563d9e4103b10e173e79e0ffa8e60 Mon Sep 17 00:00:00 2001 From: Thomas Christie Date: Fri, 8 Sep 2023 10:52:48 +0100 Subject: [PATCH 75/76] Update citation.py Updated decision-making citations to be consistent with new way of making citations. Signed-off-by: Thomas Christie --- gpjax/citation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gpjax/citation.py b/gpjax/citation.py index 3125c8bd0..57c12fc97 100644 --- a/gpjax/citation.py +++ b/gpjax/citation.py @@ -206,8 +206,8 @@ def _(tree) -> PaperCitation: #################### # Decision making citations #################### -@dispatch -def cite(tree: ThompsonSampling) -> PaperCitation: +@cite.register(ThompsonSampling) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="wilson2020efficiently", title="Efficiently sampling functions from Gaussian process posteriors", @@ -218,8 +218,8 @@ def cite(tree: ThompsonSampling) -> PaperCitation: ) -@dispatch -def cite(tree: Forrester) -> BookCitation: +@cite.register(Forrester) +def _(tree) -> BookCitation: return BookCitation( citation_key="forrester2008engineering", authors="Forrester, Alexander and Sobester, Andras and Keane, Andy", @@ -229,8 +229,8 @@ def cite(tree: Forrester) -> BookCitation: ) -@dispatch -def cite(tree: LogarithmicGoldsteinPrice) -> PaperCitation: +@cite.register(LogarithmicGoldsteinPrice) +def _(tree) -> PaperCitation: return PaperCitation( citation_key="picheny2013benchmark", authors="Picheny, Victor and Wagner, Tobias and Ginsbourger, David", From d6232fdf417f7fe8ca5442bb5b886829937dcf9d Mon Sep 17 00:00:00 2001 From: Ivan Shalashilin Date: Fri, 8 Sep 2023 14:12:59 +0100 Subject: [PATCH 76/76] formatting and spelling --- docs/examples/oceanmodelling.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/oceanmodelling.py b/docs/examples/oceanmodelling.py index 107e3f12b..a40b0ea18 100644 --- a/docs/examples/oceanmodelling.py +++ b/docs/examples/oceanmodelling.py @@ -48,7 +48,7 @@ # $$ # where $\mathbf{x} = (x^{(0)}$,$x^{(1)})^\text{T}$, with a vector basis in the standard Cartesian directions (dimensions will be indicated by superscripts). # -# We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_{,i$ is the 2-dimensional velocity vector at the $i$-th location, $\mathbf{x}_{0,i}$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). +# We shall label the ground truth $D_0=\left\{ \left(\mathbf{x}_{0,i} , \mathbf{y}_{0,i} \right)\right\}_{i=1}^N$, where $\mathbf{y}_{0,i}$ is the 2-dimensional velocity vector at the $i$-th location, $\mathbf{x}_{0,i}$. The training dataset contains simulated measurements from ocean drifters $D_T=\left\{\left(\mathbf{x}_{T,i}, \mathbf{y}_{T,i} \right)\right\}_{i=1}^{N_T}$, $N_T = 20$ in this case (the subscripts indicate the ground truth and the simulated measurements respectively). # @@ -129,7 +129,7 @@ def prepare_data(df): # \end{array}\right), # $$ # -# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar valued function. +# where each $f^{(z)}\left(\mathbf{x}\right), z \in \{0,1\}$ is a scalar-valued function. # # Now consider the scalar-valued function $g: \mathbb{R}^2 \times\{0,1\} \rightarrow \mathbb{R}$, such that # @@ -397,7 +397,7 @@ def plot_fields( # %% [markdown] # ## Helmholtz decomposition -# In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et. al, (2023)](https://arxiv.org/pdf/2302.10364.pdf)) such that +# In 2 dimensions, a twice continuously differentiable and compactly supported vector field $\mathbf{F}: \mathbb{R}^2 \rightarrow \mathbb{R}^2$ can be expressed as the sum of the gradient of a scalar potential $\Phi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the potential function, and the vorticity operator of another scalar potential $\Psi: \mathbb{R}^2 \rightarrow \mathbb{R}$, called the stream function ([Berlinghieri et al. (2023)](https://arxiv.org/pdf/2302.10364.pdf)) such that # $$ # \mathbf{F}=\operatorname{grad} \Phi+\operatorname{rot} \Psi, # $$ @@ -464,7 +464,7 @@ def __call__( # %% [markdown] -# ### GPJax iImplementation +# ### GPJax implementation # We repeat the same steps as with the velocity GP model, replacing `VelocityKernel` with `HelmholtzKernel`. # %% @@ -500,7 +500,7 @@ def __call__( # \mathrm{NLPD}=-\sum_{i=1}^{2N} \log \left( p\left(\mathcal{Y}_i = Y_{0,i} \mid \mathbf{X}_{i}\right) \right), # $$ # -# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution at each test location, and $Y_{i,0}$ is the $i$th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. +# where each $p\left(\mathcal{Y}_i \mid \mathbf{X}_i \right)$ is the marginal Gaussian distribution over $\mathcal{Y}_i$ at each test location, and $Y_{i,0}$ is the $i$-th component of the (massaged) test data that we reserved at the beginning of the notebook in $D_0$. A smaller value is better, since the deviation of the ground truth and the model are small in this case. # %%