From 6f74249a4c622682c639534235fe1d633454ff26 Mon Sep 17 00:00:00 2001 From: byd Date: Mon, 9 Jun 2025 17:39:43 -0400 Subject: [PATCH 01/15] Replace np.float_ with np.float64 for NumPy compatibility --- src/probnum/randprocs/_gaussian_process.py | 2 +- src/probnum/randprocs/markov/_markov.py | 2 +- src/probnum/randvars/_constant.py | 6 +- src/probnum/randvars/_normal.py | 24 ++++---- src/probnum/randvars/_random_variable.py | 68 +++++++++++----------- src/probnum/randvars/_scipy_stats.py | 18 +++--- 6 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/probnum/randprocs/_gaussian_process.py b/src/probnum/randprocs/_gaussian_process.py index aea560d4f..07caa3c8e 100644 --- a/src/probnum/randprocs/_gaussian_process.py +++ b/src/probnum/randprocs/_gaussian_process.py @@ -67,7 +67,7 @@ def __init__( super().__init__( input_shape=mean.input_shape, output_shape=mean.output_shape, - dtype=np.dtype(np.float_), + dtype=np.dtype(np.float64), mean=mean, cov=cov, ) diff --git a/src/probnum/randprocs/markov/_markov.py b/src/probnum/randprocs/markov/_markov.py index 7939edd3f..a98cdb67e 100644 --- a/src/probnum/randprocs/markov/_markov.py +++ b/src/probnum/randprocs/markov/_markov.py @@ -30,7 +30,7 @@ def __init__( super().__init__( input_shape=input_shape, output_shape=output_shape, - dtype=np.dtype(np.float_), + dtype=np.dtype(np.float64), mean=functions.LambdaFunction( lambda x: self.__call__(args=x).mean, input_shape=input_shape, diff --git a/src/probnum/randvars/_constant.py b/src/probnum/randvars/_constant.py index c831417d2..5deee4d6d 100644 --- a/src/probnum/randvars/_constant.py +++ b/src/probnum/randvars/_constant.py @@ -65,7 +65,7 @@ def __init__( self._support = support support_floating = self._support.astype( - np.promote_types(self._support.dtype, np.float_) + np.promote_types(self._support.dtype, np.float64) ) if config.matrix_free: @@ -95,8 +95,8 @@ def __init__( parameters={"support": self._support}, sample=self._sample, in_support=lambda x: np.all(x == self._support), - pmf=lambda x: np.float_(1.0 if np.all(x == self._support) else 0.0), - cdf=lambda x: np.float_(1.0 if np.all(x >= self._support) else 0.0), + pmf=lambda x: np.float64(1.0 if np.all(x == self._support) else 0.0), + cdf=lambda x: np.float64(1.0 if np.all(x >= self._support) else 0.0), mode=lambda: self._support, median=lambda: support_floating, mean=lambda: support_floating, diff --git a/src/probnum/randvars/_normal.py b/src/probnum/randvars/_normal.py index cdc428a57..4f0ef12c7 100644 --- a/src/probnum/randvars/_normal.py +++ b/src/probnum/randvars/_normal.py @@ -432,25 +432,25 @@ def _univariate_sample( def _univariate_in_support(x: ValueType) -> bool: return np.isfinite(x) - def _univariate_pdf(self, x: ValueType) -> np.float_: + def _univariate_pdf(self, x: ValueType) -> np.float64: return scipy.stats.norm.pdf(x, loc=self.mean, scale=self.std) - def _univariate_logpdf(self, x: ValueType) -> np.float_: + def _univariate_logpdf(self, x: ValueType) -> np.float64: return scipy.stats.norm.logpdf(x, loc=self.mean, scale=self.std) - def _univariate_cdf(self, x: ValueType) -> np.float_: + def _univariate_cdf(self, x: ValueType) -> np.float64: return scipy.stats.norm.cdf(x, loc=self.mean, scale=self.std) - def _univariate_logcdf(self, x: ValueType) -> np.float_: + def _univariate_logcdf(self, x: ValueType) -> np.float64: return scipy.stats.norm.logcdf(x, loc=self.mean, scale=self.std) def _univariate_quantile(self, p: FloatLike) -> np.floating: return scipy.stats.norm.ppf(p, loc=self.mean, scale=self.std) - def _univariate_entropy(self: ValueType) -> np.float_: + def _univariate_entropy(self: ValueType) -> np.float64: return _utils.as_numpy_scalar( scipy.stats.norm.entropy(loc=self.mean, scale=self.std), - dtype=np.float_, + dtype=np.float64, ) # Multi- and matrixvariate Gaussians @@ -500,28 +500,28 @@ def _arg_todense(x: Union[np.ndarray, linops.LinearOperator]) -> np.ndarray: def _dense_in_support(x: ValueType) -> bool: return np.all(np.isfinite(Normal._arg_todense(x))) - def _dense_pdf(self, x: ValueType) -> np.float_: + def _dense_pdf(self, x: ValueType) -> np.float64: return scipy.stats.multivariate_normal.pdf( Normal._arg_todense(x).reshape(x.shape[: -self.ndim] + (-1,)), mean=self.dense_mean.ravel(), cov=self.dense_cov, ) - def _dense_logpdf(self, x: ValueType) -> np.float_: + def _dense_logpdf(self, x: ValueType) -> np.float64: return scipy.stats.multivariate_normal.logpdf( Normal._arg_todense(x).reshape(x.shape[: -self.ndim] + (-1,)), mean=self.dense_mean.ravel(), cov=self.dense_cov, ) - def _dense_cdf(self, x: ValueType) -> np.float_: + def _dense_cdf(self, x: ValueType) -> np.float64: return scipy.stats.multivariate_normal.cdf( Normal._arg_todense(x).reshape(x.shape[: -self.ndim] + (-1,)), mean=self.dense_mean.ravel(), cov=self.dense_cov, ) - def _dense_logcdf(self, x: ValueType) -> np.float_: + def _dense_logcdf(self, x: ValueType) -> np.float64: return scipy.stats.multivariate_normal.logcdf( Normal._arg_todense(x).reshape(x.shape[: -self.ndim] + (-1,)), mean=self.dense_mean.ravel(), @@ -531,13 +531,13 @@ def _dense_logcdf(self, x: ValueType) -> np.float_: def _dense_var(self) -> np.ndarray: return np.diag(self.dense_cov).reshape(self.shape) - def _dense_entropy(self) -> np.float_: + def _dense_entropy(self) -> np.float64: return _utils.as_numpy_scalar( scipy.stats.multivariate_normal.entropy( mean=self.dense_mean.ravel(), cov=self.dense_cov, ), - dtype=np.float_, + dtype=np.float64, ) # Matrixvariate Gaussian with Kronecker covariance diff --git a/src/probnum/randvars/_random_variable.py b/src/probnum/randvars/_random_variable.py index 6f6180e55..8c0937c01 100644 --- a/src/probnum/randvars/_random_variable.py +++ b/src/probnum/randvars/_random_variable.py @@ -110,8 +110,8 @@ def __init__( parameters: Optional[Dict[str, Any]] = None, sample: Optional[Callable[[np.random.Generator, ShapeType], ValueType]] = None, in_support: Optional[Callable[[ValueType], bool]] = None, - cdf: Optional[Callable[[ValueType], np.float_]] = None, - logcdf: Optional[Callable[[ValueType], np.float_]] = None, + cdf: Optional[Callable[[ValueType], np.float64]] = None, + logcdf: Optional[Callable[[ValueType], np.float64]] = None, quantile: Optional[Callable[[FloatLike], ValueType]] = None, mode: Optional[Callable[[], ValueType]] = None, median: Optional[Callable[[], ValueType]] = None, @@ -119,7 +119,7 @@ def __init__( cov: Optional[Callable[[], ValueType]] = None, var: Optional[Callable[[], ValueType]] = None, std: Optional[Callable[[], ValueType]] = None, - entropy: Optional[Callable[[], np.float_]] = None, + entropy: Optional[Callable[[], np.float64]] = None, as_value_type: Optional[Callable[[Any], ValueType]] = None, ): # pylint: disable=too-many-arguments,too-many-locals @@ -370,7 +370,7 @@ def std(self) -> ValueType: return std @cached_property - def entropy(self) -> np.float_: + def entropy(self) -> np.float64: """Information-theoretic entropy :math:`H(X)` of the random variable.""" if self.__entropy is None: raise NotImplementedError @@ -424,7 +424,7 @@ def sample(self, rng: np.random.Generator, size: ShapeLike = ()) -> ValueType: return self.__sample(rng=rng, size=_utils.as_shape(size)) - def cdf(self, x: ValueType) -> np.float_: + def cdf(self, x: ValueType) -> np.float64: """Cumulative distribution function. Parameters @@ -442,7 +442,7 @@ def cdf(self, x: ValueType) -> np.float_: if self.__logcdf is not None: cdf = np.exp(self.logcdf(self._as_value_type(x))) - assert isinstance(cdf, np.float_) + assert isinstance(cdf, np.float64) return cdf raise NotImplementedError( @@ -450,7 +450,7 @@ def cdf(self, x: ValueType) -> np.float_: f"with type `{type(self).__name__}` is implemented." ) - def logcdf(self, x: ValueType) -> np.float_: + def logcdf(self, x: ValueType) -> np.float64: """Log-cumulative distribution function. Parameters @@ -468,7 +468,7 @@ def logcdf(self, x: ValueType) -> np.float_: if self.__cdf is not None: logcdf = np.log(self.__cdf(x)) - assert isinstance(logcdf, np.float_) + assert isinstance(logcdf, np.float64) return logcdf raise NotImplementedError( @@ -779,7 +779,7 @@ def infer_moment_dtype(value_dtype: DTypeLike) -> np.dtype: value_dtype : Dtype of a value. """ - return np.promote_types(value_dtype, np.float_) + return np.promote_types(value_dtype, np.float64) def _as_value_type(self, x: Any) -> ValueType: if self.__as_value_type is not None: @@ -811,26 +811,26 @@ def _check_property_value( @classmethod def _ensure_numpy_float( cls, name: str, value: Any, force_scalar: bool = False - ) -> Union[np.float_, np.ndarray]: + ) -> Union[np.float64, np.ndarray]: if np.isscalar(value): - if not isinstance(value, np.float_): + if not isinstance(value, np.float64): try: - value = _utils.as_numpy_scalar(value, dtype=np.float_) + value = _utils.as_numpy_scalar(value, dtype=np.float64) except TypeError as err: raise TypeError( f"The function `{name}` specified via the constructor of " f"`{cls.__name__}` must return a scalar value that can be " - f"converted to a `np.float_`, which is not possible for " + f"converted to a `np.float64`, which is not possible for " f"{value} of type {type(value)}." ) from err elif not force_scalar: try: - value = np.asarray(value, dtype=np.float_) + value = np.asarray(value, dtype=np.float64) except TypeError as err: raise TypeError( f"The function `{name}` specified via the constructor of " f"`{cls.__name__}` must return a value that can be converted " - f"to a `np.ndarray` of type `np.float_`, which is not possible " + f"to a `np.ndarray` of type `np.float64`, which is not possible " f"for {value} of type {type(value)}." ) from err else: @@ -840,7 +840,7 @@ def _ensure_numpy_float( f"{type(value)} is not scalar." ) - assert isinstance(value, (np.float_, np.ndarray)) + assert isinstance(value, (np.float64, np.ndarray)) return value @@ -962,10 +962,10 @@ def __init__( parameters: Optional[Dict[str, Any]] = None, sample: Optional[Callable[[np.random.Generator, ShapeLike], ValueType]] = None, in_support: Optional[Callable[[ValueType], bool]] = None, - pmf: Optional[Callable[[ValueType], np.float_]] = None, - logpmf: Optional[Callable[[ValueType], np.float_]] = None, - cdf: Optional[Callable[[ValueType], np.float_]] = None, - logcdf: Optional[Callable[[ValueType], np.float_]] = None, + pmf: Optional[Callable[[ValueType], np.float64]] = None, + logpmf: Optional[Callable[[ValueType], np.float64]] = None, + cdf: Optional[Callable[[ValueType], np.float64]] = None, + logcdf: Optional[Callable[[ValueType], np.float64]] = None, quantile: Optional[Callable[[FloatLike], ValueType]] = None, mode: Optional[Callable[[], ValueType]] = None, median: Optional[Callable[[], ValueType]] = None, @@ -973,7 +973,7 @@ def __init__( cov: Optional[Callable[[], ValueType]] = None, var: Optional[Callable[[], ValueType]] = None, std: Optional[Callable[[], ValueType]] = None, - entropy: Optional[Callable[[], np.float_]] = None, + entropy: Optional[Callable[[], np.float64]] = None, as_value_type: Optional[Callable[[Any], ValueType]] = None, ): # Probability mass function @@ -999,7 +999,7 @@ def __init__( as_value_type=as_value_type, ) - def pmf(self, x: ValueType) -> np.float_: + def pmf(self, x: ValueType) -> np.float64: """Probability mass function. Computes the probability of the random variable being equal to the given @@ -1024,7 +1024,7 @@ def pmf(self, x: ValueType) -> np.float_: if self.__logpmf is not None: pmf = np.exp(self.__logpmf(x)) - assert isinstance(pmf, np.float_) + assert isinstance(pmf, np.float64) return pmf raise NotImplementedError( @@ -1032,7 +1032,7 @@ def pmf(self, x: ValueType) -> np.float_: f"object with type `{type(self).__name__}` is implemented." ) - def logpmf(self, x: ValueType) -> np.float_: + def logpmf(self, x: ValueType) -> np.float64: """Natural logarithm of the probability mass function. Parameters @@ -1050,7 +1050,7 @@ def logpmf(self, x: ValueType) -> np.float_: if self.__pmf is not None: logpmf = np.log(self.__pmf(self._as_value_type(x))) - assert isinstance(logpmf, np.float_) + assert isinstance(logpmf, np.float64) return logpmf raise NotImplementedError( @@ -1176,10 +1176,10 @@ def __init__( parameters: Optional[Dict[str, Any]] = None, sample: Optional[Callable[[np.random.Generator, ShapeLike], ValueType]] = None, in_support: Optional[Callable[[ValueType], bool]] = None, - pdf: Optional[Callable[[ValueType], np.float_]] = None, - logpdf: Optional[Callable[[ValueType], np.float_]] = None, - cdf: Optional[Callable[[ValueType], np.float_]] = None, - logcdf: Optional[Callable[[ValueType], np.float_]] = None, + pdf: Optional[Callable[[ValueType], np.float64]] = None, + logpdf: Optional[Callable[[ValueType], np.float64]] = None, + cdf: Optional[Callable[[ValueType], np.float64]] = None, + logcdf: Optional[Callable[[ValueType], np.float64]] = None, quantile: Optional[Callable[[FloatLike], ValueType]] = None, mode: Optional[Callable[[], ValueType]] = None, median: Optional[Callable[[], ValueType]] = None, @@ -1187,7 +1187,7 @@ def __init__( cov: Optional[Callable[[], ValueType]] = None, var: Optional[Callable[[], ValueType]] = None, std: Optional[Callable[[], ValueType]] = None, - entropy: Optional[Callable[[], np.float_]] = None, + entropy: Optional[Callable[[], np.float64]] = None, as_value_type: Optional[Callable[[Any], ValueType]] = None, ): # Probability density function @@ -1213,7 +1213,7 @@ def __init__( as_value_type=as_value_type, ) - def pdf(self, x: ValueType) -> np.float_: + def pdf(self, x: ValueType) -> np.float64: """Probability density function. The area under the curve defined by the probability density function @@ -1240,7 +1240,7 @@ def pdf(self, x: ValueType) -> np.float_: if self.__logpdf is not None: pdf = np.exp(self.__logpdf(self._as_value_type(x))) - assert isinstance(pdf, np.float_) + assert isinstance(pdf, np.float64) return pdf raise NotImplementedError( @@ -1248,7 +1248,7 @@ def pdf(self, x: ValueType) -> np.float_: f"object with type `{type(self).__name__}` is implemented." ) - def logpdf(self, x: ValueType) -> np.float_: + def logpdf(self, x: ValueType) -> np.float64: """Natural logarithm of the probability density function. Parameters @@ -1266,7 +1266,7 @@ def logpdf(self, x: ValueType) -> np.float_: if self.__pdf is not None: logpdf = np.log(self.__pdf(self._as_value_type(x))) - assert isinstance(logpdf, np.float_) + assert isinstance(logpdf, np.float64) return logpdf raise NotImplementedError( diff --git a/src/probnum/randvars/_scipy_stats.py b/src/probnum/randvars/_scipy_stats.py index a8ae6359d..36b8470b0 100644 --- a/src/probnum/randvars/_scipy_stats.py +++ b/src/probnum/randvars/_scipy_stats.py @@ -74,12 +74,12 @@ def __init__( rv_kwargs["pmf"] = _return_numpy( getattr(scipy_rv, "pmf", None), - dtype=np.float_, + dtype=np.float64, ) rv_kwargs["logpmf"] = _return_numpy( getattr(scipy_rv, "logpmf", None), - dtype=np.float_, + dtype=np.float64, ) super().__init__(**rv_kwargs) @@ -113,12 +113,12 @@ def __init__( rv_kwargs["pdf"] = _return_numpy( getattr(scipy_rv, "pdf", None), - dtype=np.float_, + dtype=np.float64, ) rv_kwargs["logpdf"] = _return_numpy( getattr(scipy_rv, "logpdf", None), - dtype=np.float_, + dtype=np.float64, ) super().__init__(**rv_kwargs) @@ -211,8 +211,8 @@ def _rv_init_kwargs_from_scipy_rv( shape = sample.shape dtype = sample.dtype - median_dtype = np.promote_types(dtype, np.float_) - moments_dtype = np.promote_types(dtype, np.float_) + median_dtype = np.promote_types(dtype, np.float64) + moments_dtype = np.promote_types(dtype, np.float64) # Support of univariate random variables if isinstance(scipy_rv, scipy.stats._distn_infrastructure.rv_frozen): @@ -238,8 +238,8 @@ def sample_from_scipy_rv(rng, size): "dtype": dtype, "sample": _return_numpy(sample_wrapper, dtype), "in_support": in_support, - "cdf": _return_numpy(getattr(scipy_rv, "cdf", None), np.float_), - "logcdf": _return_numpy(getattr(scipy_rv, "logcdf", None), np.float_), + "cdf": _return_numpy(getattr(scipy_rv, "cdf", None), np.float64), + "logcdf": _return_numpy(getattr(scipy_rv, "logcdf", None), np.float64), "quantile": _return_numpy(getattr(scipy_rv, "ppf", None), dtype), "mode": None, # not offered by scipy.stats "median": _return_numpy(getattr(scipy_rv, "median", None), median_dtype), @@ -247,7 +247,7 @@ def sample_from_scipy_rv(rng, size): "cov": _return_numpy(getattr(scipy_rv, "cov", None), moments_dtype), "var": _return_numpy(getattr(scipy_rv, "var", None), moments_dtype), "std": _return_numpy(getattr(scipy_rv, "std", None), moments_dtype), - "entropy": _return_numpy(getattr(scipy_rv, "entropy", None), np.float_), + "entropy": _return_numpy(getattr(scipy_rv, "entropy", None), np.float64), } From c53f6dda1a7c6c88047b8637378b5761176b6cc5 Mon Sep 17 00:00:00 2001 From: byd Date: Mon, 9 Jun 2025 18:19:50 -0400 Subject: [PATCH 02/15] Fix NumPy 2.0 compatibility: replace np.find_common_type with np.result_type - Replace deprecated np.find_common_type calls in SumLinearOperator and ProductLinearOperator - Use functools.reduce with np.result_type to achieve same functionality - Fixes AttributeError when using NumPy 2.0+ --- src/probnum/linops/_arithmetic_fallbacks.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/probnum/linops/_arithmetic_fallbacks.py b/src/probnum/linops/_arithmetic_fallbacks.py index 52f7c73ec..7564bcd72 100644 --- a/src/probnum/linops/_arithmetic_fallbacks.py +++ b/src/probnum/linops/_arithmetic_fallbacks.py @@ -97,9 +97,7 @@ def __init__(self, *summands: LinearOperator): super().__init__( shape=summands[0].shape, - dtype=np.find_common_type( - [summand.dtype for summand in self._summands], [] - ), + dtype=functools.reduce(np.result_type, [summand.dtype for summand in self._summands]), matmul=lambda x: functools.reduce( operator.add, (summand @ x for summand in self._summands) ), @@ -190,7 +188,7 @@ def __init__(self, *factors: LinearOperator): super().__init__( shape=(self._factors[0].shape[0], self._factors[-1].shape[1]), - dtype=np.find_common_type([factor.dtype for factor in self._factors], []), + dtype=functools.reduce(np.result_type, [factor.dtype for factor in self._factors]), matmul=lambda x: functools.reduce( lambda vec, op: op @ vec, reversed(self._factors), x ), From d8b60992e55816baa6d6ea6ea875335503bea2ba Mon Sep 17 00:00:00 2001 From: byd Date: Tue, 10 Jun 2025 11:29:18 -0400 Subject: [PATCH 03/15] Update probnum modifications for linpde-gp integration --- docs/source/development/implementing_a_probnum_method.ipynb | 2 +- .../development/quadopt_example/observation_operators.py | 2 +- .../source/tutorials/linops/linear_operators_quickstart.ipynb | 4 ++-- src/probnum/linops/_linear_operator.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/development/implementing_a_probnum_method.ipynb b/docs/source/development/implementing_a_probnum_method.ipynb index 8f27e9549..605ec1b18 100644 --- a/docs/source/development/implementing_a_probnum_method.ipynb +++ b/docs/source/development/implementing_a_probnum_method.ipynb @@ -728,7 +728,7 @@ "# %load -s function_evaluation quadopt_example/observation_operators\n", "def function_evaluation(\n", " fun: Callable[[FloatLike], FloatLike], action: FloatLike\n", - ") -> np.float_:\n", + ") -> np.float64:\n", " \"\"\"Observe a (noisy) function evaluation of the quadratic objective.\n", "\n", " Parameters\n", diff --git a/docs/source/development/quadopt_example/observation_operators.py b/docs/source/development/quadopt_example/observation_operators.py index a08e25cf4..bb5b7e6ff 100644 --- a/docs/source/development/quadopt_example/observation_operators.py +++ b/docs/source/development/quadopt_example/observation_operators.py @@ -10,7 +10,7 @@ def function_evaluation( fun: Callable[[FloatLike], FloatLike], action: FloatLike -) -> np.float_: +) -> np.float64: """Observe a (noisy) function evaluation of the quadratic objective. Parameters diff --git a/docs/source/tutorials/linops/linear_operators_quickstart.ipynb b/docs/source/tutorials/linops/linear_operators_quickstart.ipynb index 5f533847f..90b2523f4 100644 --- a/docs/source/tutorials/linops/linear_operators_quickstart.ipynb +++ b/docs/source/tutorials/linops/linear_operators_quickstart.ipynb @@ -380,7 +380,7 @@ " return np.roll(v, 1)\n", "\n", "n = 5\n", - "P_op = LambdaLinearOperator(shape=(n, n), dtype=np.float_, matmul=mv)\n", + "P_op = LambdaLinearOperator(shape=(n, n), dtype=np.float64, matmul=mv)\n", "x = np.arange(0., n, 1)\n", "\n", "P_op" @@ -512,7 +512,7 @@ "def mv(v):\n", " return v[:n-1]\n", "\n", - "Pr = LambdaLinearOperator(shape=(n-1, n), dtype=np.float_, matmul=mv)\n", + "Pr = LambdaLinearOperator(shape=(n-1, n), dtype=np.float64, matmul=mv)\n", "\n", "# Apply the operator to the 3D normal random variable\n", "rv_projected = Pr @ rv" diff --git a/src/probnum/linops/_linear_operator.py b/src/probnum/linops/_linear_operator.py index 5a4b3ca81..f0b08fd3f 100644 --- a/src/probnum/linops/_linear_operator.py +++ b/src/probnum/linops/_linear_operator.py @@ -1308,7 +1308,7 @@ class LambdaLinearOperator( # pylint: disable=too-many-instance-attributes ... def mv(v): ... return np.array([2 * v[0] - v[1], 3 * v[1]]) - >>> A = LambdaLinearOperator(shape=(2, 2), dtype=np.float_, matmul=mv) + >>> A = LambdaLinearOperator(shape=(2, 2), dtype=np.float64, matmul=mv) >>> A From 6fb2a5aa263482068e30df0cee891591a7c7598b Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 16:57:12 +0200 Subject: [PATCH 04/15] UPD: pre-commit configuration. --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9bdebb661..1e8056ef9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ default_language_version: python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v5.0.0 hooks: - id: check-added-large-files # Default is 500 which is too strict on the notebooks. @@ -31,7 +31,7 @@ repos: # exclude autogenerated files exclude: /README\.rst$|\.pot?$ - repo: https://github.com/psf/black - rev: 22.3.0 # Make sure to use the same tag/version as specified in formatting-requirements.txt + rev: 25.1.0 # Make sure to use the same tag/version as specified in formatting-requirements.txt hooks: - id: black language_version: python3 @@ -40,7 +40,7 @@ repos: hooks: - id: isort - repo: https://github.com/myint/docformatter - rev: v1.3.1 + rev: v1.7.7 hooks: - id: docformatter args: ['--in-place', From 61a25fb16ab7713e317e38a4807e140269fdad33 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 16:57:32 +0200 Subject: [PATCH 05/15] FIX: missing commata --- docs/notebook-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/notebook-requirements.txt b/docs/notebook-requirements.txt index dcc80aadc..3d912a5f7 100644 --- a/docs/notebook-requirements.txt +++ b/docs/notebook-requirements.txt @@ -1,5 +1,5 @@ # Jupyter notebooks -ipython>=8.9.0<8.11.0 +ipython>=8.9.0,<8.11.0 jupyter # Notebook conversion From 98a3b61c99e0638806832b91e9328fb8a5e65d99 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 17:04:54 +0200 Subject: [PATCH 06/15] FIX" numpy 2.0 compatibility by switching `np.Inf` -> `np.inf`. --- src/probnum/quad/integration_measures/_gaussian_measure.py | 3 +-- src/probnum/quad/integration_measures/_lebesgue_measure.py | 3 +-- src/probnum/quad/solvers/initial_designs/_latin_design.py | 3 +-- src/probnum/quad/solvers/policies/_van_der_corput_policy.py | 2 +- tests/test_quad/test_integration_measure.py | 2 +- tests/test_quad/test_policy.py | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/probnum/quad/integration_measures/_gaussian_measure.py b/src/probnum/quad/integration_measures/_gaussian_measure.py index a7459fe1b..5aa1f6b89 100644 --- a/src/probnum/quad/integration_measures/_gaussian_measure.py +++ b/src/probnum/quad/integration_measures/_gaussian_measure.py @@ -1,6 +1,5 @@ """The Gaussian measure.""" - from __future__ import annotations from typing import Optional, Union @@ -55,7 +54,7 @@ def __init__( input_dim = mean.size # Set domain as whole R^n - domain = (np.full((input_dim,), -np.Inf), np.full((input_dim,), np.Inf)) + domain = (np.full((input_dim,), -np.inf), np.full((input_dim,), np.inf)) super().__init__(input_dim=input_dim, domain=domain) # Exploit random variables to carry out mean and covariance checks diff --git a/src/probnum/quad/integration_measures/_lebesgue_measure.py b/src/probnum/quad/integration_measures/_lebesgue_measure.py index 27a5bed70..eebdedcae 100644 --- a/src/probnum/quad/integration_measures/_lebesgue_measure.py +++ b/src/probnum/quad/integration_measures/_lebesgue_measure.py @@ -1,6 +1,5 @@ """The Lebesgue measure.""" - from __future__ import annotations from typing import Optional @@ -43,7 +42,7 @@ def __init__( else: normalization_constant = 1.0 - if normalization_constant in [0, np.Inf, -np.Inf]: + if normalization_constant in [0, np.inf, -np.inf]: raise ValueError( "Normalization constant is too small or too large. " "Consider setting normalized = False." diff --git a/src/probnum/quad/solvers/initial_designs/_latin_design.py b/src/probnum/quad/solvers/initial_designs/_latin_design.py index 553b494fc..b359e5837 100644 --- a/src/probnum/quad/solvers/initial_designs/_latin_design.py +++ b/src/probnum/quad/solvers/initial_designs/_latin_design.py @@ -28,11 +28,10 @@ class LatinDesign(InitialDesign): ---------- .. [1] Mckay et al., A Comparison of Three Methods for Selecting Values of Input Variables in the Analysis of Output from a Computer Code. Technometrics, 1979. - """ def __init__(self, n_nodes: IntLike, measure: IntegrationMeasure) -> None: - if np.Inf in np.hstack([abs(measure.domain[0]), abs(measure.domain[1])]): + if np.inf in np.hstack([abs(measure.domain[0]), abs(measure.domain[1])]): raise ValueError( "Latin hypercube samples require a finite domain. " "At least one dimension seems to be unbounded." diff --git a/src/probnum/quad/solvers/policies/_van_der_corput_policy.py b/src/probnum/quad/solvers/policies/_van_der_corput_policy.py index ec31bcee1..95bb04691 100644 --- a/src/probnum/quad/solvers/policies/_van_der_corput_policy.py +++ b/src/probnum/quad/solvers/policies/_van_der_corput_policy.py @@ -50,7 +50,7 @@ def __init__(self, batch_size: IntLike, measure: IntegrationMeasure) -> None: domain_a = measure.domain[0] domain_b = measure.domain[1] - if np.Inf in np.hstack([abs(domain_a), abs(domain_b)]): + if np.inf in np.hstack([abs(domain_a), abs(domain_b)]): raise ValueError("Policy 'vdc' works only for bounded domains.") self.domain_a = domain_a diff --git a/tests/test_quad/test_integration_measure.py b/tests/test_quad/test_integration_measure.py index 6b1e8351e..0ea19680c 100644 --- a/tests/test_quad/test_integration_measure.py +++ b/tests/test_quad/test_integration_measure.py @@ -162,7 +162,7 @@ def test_lebesgue_domain_input_dim_mismatch_raises(input_dim, domain): LebesgueMeasure(input_dim=input_dim, domain=domain) -@pytest.mark.parametrize("domain", [(0, np.Inf), (-np.Inf, 0), (-np.Inf, np.Inf)]) +@pytest.mark.parametrize("domain", [(0, np.inf), (-np.inf, 0), (-np.inf, np.inf)]) def test_lebesgue_normalization_raises(domain, input_dim: int): """Check that exception is raised when normalization is not possible.""" with pytest.raises(ValueError): diff --git a/tests/test_quad/test_policy.py b/tests/test_quad/test_policy.py index 5e3c963d1..5db88c215 100644 --- a/tests/test_quad/test_policy.py +++ b/tests/test_quad/test_policy.py @@ -222,7 +222,7 @@ def test_van_der_corput_multi_d_error(): VanDerCorputPolicy(1, measure) -@pytest.mark.parametrize("domain", [(-np.Inf, 0), (1, np.Inf), (-np.Inf, np.Inf)]) +@pytest.mark.parametrize("domain", [(-np.inf, 0), (1, np.inf), (-np.inf, np.inf)]) def test_van_der_corput_infinite_error(domain): """Check that van der Corput policy fails on infinite domains.""" measure = LebesgueMeasure(input_dim=1, domain=domain) From 0375ae9a42c8a2ac24d5298956882c962ba4fddc Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 18:00:13 +0200 Subject: [PATCH 07/15] UPD: jax dependency to be compatible with numpy 2.0. --- .../diffeq/odefilter/init_routines/_autodiff.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/probnum/diffeq/odefilter/init_routines/_autodiff.py b/src/probnum/diffeq/odefilter/init_routines/_autodiff.py index 933c00917..06d08b528 100644 --- a/src/probnum/diffeq/odefilter/init_routines/_autodiff.py +++ b/src/probnum/diffeq/odefilter/init_routines/_autodiff.py @@ -11,14 +11,14 @@ # pylint: disable="import-outside-toplevel" try: import jax - from jax.config import config + from jax import config from jax.experimental.jet import jet import jax.numpy as jnp config.update("jax_enable_x64", True) JAX_IS_AVAILABLE = True -except ImportError as JAX_IMPORT_ERROR: +except ImportError: JAX_IS_AVAILABLE = False JAX_IMPORT_ERROR_MSG = ( "Cannot perform Jax-based initialization without the optional " @@ -31,7 +31,7 @@ class _AutoDiffBase(InitializationRoutine): def __init__(self): if not JAX_IS_AVAILABLE: - raise ImportError(JAX_IMPORT_ERROR_MSG) from JAX_IMPORT_ERROR + raise ImportError(JAX_IMPORT_ERROR_MSG) super().__init__(is_exact=True, requires_jax=True) @@ -70,12 +70,12 @@ def _make_autonomous(self, *, ivp): Turn the ODE into a format that is more convenient to handle with automatic differentiation. This has no effect on the ODE itself. It is purely internal. """ - y0_autonomous = jnp.concatenate([ivp.y0, jnp.array([ivp.t0])]) + y0_autonomous = jnp.concatenate([ivp.y0, jnp.asarray([ivp.t0])]) def f_autonomous(y): x, t = y[:-1], y[-1] fx = ivp.f(t, x) - return jnp.concatenate([fx, jnp.array([1.0])]) + return jnp.concatenate([fx, jnp.asarray([1.0])]) return f_autonomous, y0_autonomous From 29766b7c5cce4bf648f5bdbedc4f4ae421222577 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 18:02:20 +0200 Subject: [PATCH 08/15] FIX: `black` formatting error. --- src/probnum/linops/_arithmetic_fallbacks.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/probnum/linops/_arithmetic_fallbacks.py b/src/probnum/linops/_arithmetic_fallbacks.py index c1db8694a..39114b3c7 100644 --- a/src/probnum/linops/_arithmetic_fallbacks.py +++ b/src/probnum/linops/_arithmetic_fallbacks.py @@ -1,4 +1,5 @@ """Fallback-implementations of LinearOperator arithmetic.""" + from __future__ import annotations import functools @@ -97,7 +98,9 @@ def __init__(self, *summands: LinearOperator): super().__init__( shape=summands[0].shape, - dtype=functools.reduce(np.result_type, [summand.dtype for summand in self._summands]), + dtype=functools.reduce( + np.result_type, [summand.dtype for summand in self._summands] + ), matmul=lambda x: functools.reduce( operator.add, (summand @ x for summand in self._summands) ), @@ -190,7 +193,9 @@ def __init__(self, *factors: LinearOperator): super().__init__( shape=(self._factors[0].shape[0], self._factors[-1].shape[1]), - dtype=functools.reduce(np.result_type, [factor.dtype for factor in self._factors]), + dtype=functools.reduce( + np.result_type, [factor.dtype for factor in self._factors] + ), matmul=lambda x: functools.reduce( lambda vec, op: op @ vec, reversed(self._factors), x ), From 264ea40ae1bd842de0209078db421dee0235ffee Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 18:15:27 +0200 Subject: [PATCH 09/15] FIX: `jax` requirement. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 928969f13..0daf8c518 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ # `pyproject.toml`, once optional dependencies defined there can reference one another extras_require = dict() extras_require["jax"] = [ - "jax[cpu]<0.4.20; platform_system!='Windows'", + "jax[cpu]>=0.4.26; platform_system!='Windows'", ] extras_require["zoo"] = [ "tqdm>=4.0", From dbde433949aac9b915e38866efe938ef13d35868 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 22:50:54 +0200 Subject: [PATCH 10/15] FIX: Use `math` instead of `numpy.math`. --- src/probnum/problems/zoo/quad/_quadproblems_uniform.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/probnum/problems/zoo/quad/_quadproblems_uniform.py b/src/probnum/problems/zoo/quad/_quadproblems_uniform.py index 7883e49d5..8268ac820 100644 --- a/src/probnum/problems/zoo/quad/_quadproblems_uniform.py +++ b/src/probnum/problems/zoo/quad/_quadproblems_uniform.py @@ -1,6 +1,7 @@ """Test problems for integration against the Lebesgue measure.""" import itertools +import math import numpy as np from scipy.stats import norm @@ -182,7 +183,7 @@ def fun(x: np.ndarray) -> np.ndarray: solution = solution + ((-1.0) ** (k + dim)) * ( 1.0 + np.sum(a) - np.sum(a_subset) ) ** (-1) - solution = solution / (np.prod(a) * np.math.factorial(dim)) + solution = solution / (np.prod(a) * math.factorial(dim)) lower_bd = np.broadcast_to(0.0, dim) upper_bd = np.broadcast_to(1.0, dim) From 9b4582efe53e2bcf55eadaaf14538069c46e73d8 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 22:53:21 +0200 Subject: [PATCH 11/15] FIX: Update keyword `newshape` -> `shape`. --- .../quad/integration_measures/_integration_measure.py | 2 +- src/probnum/utils/arrayutils.py | 4 ++-- tests/test_randvars/test_random_variable.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/probnum/quad/integration_measures/_integration_measure.py b/src/probnum/quad/integration_measures/_integration_measure.py index e8e7f9da4..05f899599 100644 --- a/src/probnum/quad/integration_measures/_integration_measure.py +++ b/src/probnum/quad/integration_measures/_integration_measure.py @@ -73,5 +73,5 @@ def sample( # pylint: disable=no-member return np.reshape( self.random_variable.sample(size=n_sample, rng=rng), - newshape=(n_sample, self.input_dim), + shape=(n_sample, self.input_dim), ) diff --git a/src/probnum/utils/arrayutils.py b/src/probnum/utils/arrayutils.py index 279de4d56..64f2d8cfb 100644 --- a/src/probnum/utils/arrayutils.py +++ b/src/probnum/utils/arrayutils.py @@ -48,7 +48,7 @@ def atleast_1d( # pylint: disable=missing-raises-doc def as_colvec( - vec: Union[np.ndarray, "probnum.randvars.RandomVariable"] + vec: Union[np.ndarray, "probnum.randvars.RandomVariable"], ) -> Union[np.ndarray, "probnum.randvars.RandomVariable"]: """Transform the given vector or random variable to column format. Given a vector (or random variable) of dimension (n,) return an array with dimensions (n, 1) @@ -61,7 +61,7 @@ def as_colvec( """ if isinstance(vec, probnum.randvars.RandomVariable): if vec.shape != (vec.shape[0], 1): - vec.reshape(newshape=(vec.shape[0], 1)) + vec.reshape(shape=(vec.shape[0], 1)) elif vec.ndim == 1: return vec[:, None] return vec diff --git a/tests/test_randvars/test_random_variable.py b/tests/test_randvars/test_random_variable.py index 81713c081..c67bd69ca 100644 --- a/tests/test_randvars/test_random_variable.py +++ b/tests/test_randvars/test_random_variable.py @@ -104,7 +104,7 @@ class ArithmeticTestCase(RandomVariableTestCase): def test_rv_addition(self): """Addition with random variables.""" - for (x, rv) in list(itertools.product(self.arrays2d, self.randvars2d)): + for x, rv in list(itertools.product(self.arrays2d, self.randvars2d)): with self.subTest(): z1 = x + rv z2 = rv + x @@ -115,7 +115,7 @@ def test_rv_addition(self): def test_rv_scalarmult(self): """Multiplication of random variables with scalar constants.""" - for (alpha, rv) in list(itertools.product(self.scalars, self.randvars2d)): + for alpha, rv in list(itertools.product(self.scalars, self.randvars2d)): with self.subTest(): if np.isinf(alpha): with self.assertWarns(RuntimeWarning): @@ -199,7 +199,7 @@ def test_reshape(self): for shape in [(4, 1), (2, 2), (4,), (1, 4)]: with self.subTest(): try: - reshaped_rv = rv.reshape(newshape=shape) + reshaped_rv = rv.reshape(shape=shape) self.assertEqual(reshaped_rv.shape, shape) self.assertEqual( @@ -211,7 +211,7 @@ def test_reshape(self): for shape in [(2, 1), (2,), (1, 2)]: with self.subTest(): try: - reshaped_rv = rv.reshape(newshape=shape) + reshaped_rv = rv.reshape(shape=shape) self.assertEqual(reshaped_rv.shape, shape) self.assertEqual( From 37eeabb6da231647599301288137d858f18d5e83 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 22:54:23 +0200 Subject: [PATCH 12/15] FIX: Specify `tol` as `rtol`. --- tests/test_linalg/test_problinsolve.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_linalg/test_problinsolve.py b/tests/test_linalg/test_problinsolve.py index a5a50f25e..d4168f374 100644 --- a/tests/test_linalg/test_problinsolve.py +++ b/tests/test_linalg/test_problinsolve.py @@ -1,4 +1,5 @@ """Tests for linear solvers.""" + import os import unittest @@ -333,8 +334,8 @@ def test_matrixprior(self): ) def test_searchdir_conjugacy(self): - """Search directions should remain A-conjugate up to machine precision, - i.e. s_i^T A s_j = 0 for i != j.""" + """Search directions should remain A-conjugate up to machine precision, i.e. + s_i^T A s_j = 0 for i != j.""" searchdirs = [] # Define callback function to obtain search directions @@ -382,7 +383,7 @@ def callback_iterates_CG(xk): # Conjugate gradient method xhat_cg, info_cg = scipy.sparse.linalg.cg( - A=A, b=b, x0=x0, tol=10**-6, callback=callback_iterates_CG + A=A, b=b, x0=x0, rtol=10**-6, callback=callback_iterates_CG ) cg_iters_arr = np.array([x0] + cg_iterates) @@ -413,7 +414,7 @@ def callback_iterates_PLS( Ainv0=Ainv0, A0=A0, callback=callback_iterates_PLS, - **kwargs + **kwargs, ) pls_iters_arr = np.array([x0] + pls_iterates) From 5845b96e759955a0c779b101e80e0f7be9dd2167 Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 23:02:45 +0200 Subject: [PATCH 13/15] FIX: -> . --- src/probnum/linops/_linear_operator.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/probnum/linops/_linear_operator.py b/src/probnum/linops/_linear_operator.py index 9aa3d1dba..be64b693f 100644 --- a/src/probnum/linops/_linear_operator.py +++ b/src/probnum/linops/_linear_operator.py @@ -187,11 +187,11 @@ def __call__(self, x: np.ndarray, axis: Optional[int] = None) -> np.ndarray: ------ ValueError If the shape of :code:`x` is invalid. - numpy.AxisError + numpy.exceptions.AxisError If the axis argument is not within the valid range. """ if axis is not None and (axis < -x.ndim or axis >= x.ndim): - raise np.AxisError(axis, ndim=x.ndim) + raise np.exceptions.AxisError(axis, ndim=x.ndim) if x.ndim == 1: return self @ x @@ -964,7 +964,7 @@ def transpose(self, *axes: Union[int, Tuple[int]]) -> "LinearOperator": ------ ValueError If the given axis indices do not constitute a valid permutation of the axes. - numpy.AxisError + numpy.exceptions.AxisError If the axis indices are out of bounds. """ if len(axes) > 0: @@ -983,7 +983,7 @@ def transpose(self, *axes: Union[int, Tuple[int]]) -> "LinearOperator": axis = int(axis) if not -2 <= axis <= 1: - raise np.AxisError(axis, ndim=2) + raise np.exceptions.AxisError(axis, ndim=2) if axis < 0: axis += 2 @@ -1099,10 +1099,11 @@ def _symmetrize(self) -> LinearOperator: #################################################################################### __array_ufunc__ = None - """ - This prevents numpy from calling elementwise arithmetic operations allowing + """This prevents numpy from calling elementwise arithmetic operations allowing expressions like `y = np.array([1, 1]) + linop` to call the arithmetic operations - defined by `LinearOperator` instead of elementwise. Thus no array of + defined by `LinearOperator` instead of elementwise. + + Thus no array of `LinearOperator`s but a `LinearOperator` with the correct shape is returned. """ @@ -1264,9 +1265,8 @@ def __rmatmul__( class LambdaLinearOperator( # pylint: disable=too-many-instance-attributes LinearOperator ): - r"""Convenience subclass of LinearOperator that lets you pass - implementations of its methods as parameters instead of - overriding them in a subclass. + r"""Convenience subclass of LinearOperator that lets you pass implementations of its + methods as parameters instead of overriding them in a subclass. ``shape``, ``dtype`` and ``matmul`` must be passed, the other parameters are optional. From 30e5f4d4a228aac8610bdaaed9206ea4d7edf5cc Mon Sep 17 00:00:00 2001 From: 2bys Date: Tue, 24 Jun 2025 23:03:38 +0200 Subject: [PATCH 14/15] FIX: np.in1d -> np.isin --- src/probnum/filtsmooth/utils/_merge_regression_problems.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/probnum/filtsmooth/utils/_merge_regression_problems.py b/src/probnum/filtsmooth/utils/_merge_regression_problems.py index ce5dfc886..7f48b7072 100644 --- a/src/probnum/filtsmooth/utils/_merge_regression_problems.py +++ b/src/probnum/filtsmooth/utils/_merge_regression_problems.py @@ -1,6 +1,5 @@ """Utility functions for filtering and smoothing.""" - from typing import Tuple import numpy as np @@ -103,7 +102,7 @@ def merge_regression_problems( ) # Merge time locations - if np.any(np.in1d(locs1, locs2)): + if np.any(np.isin(locs1, locs2)): raise ValueError("Regression problems must not share time locations.") new_locs = np.sort(np.concatenate((locs1, locs2))) locs1_in_new_locs = np.searchsorted(new_locs, locs1) From 1464581488df7ae166901cf30effd6c455d8be82 Mon Sep 17 00:00:00 2001 From: 2bys Date: Wed, 25 Jun 2025 03:57:41 +0200 Subject: [PATCH 15/15] FIX: Regarding pykeops and docstringtest with numpy 2.0. UPD: Whitespace changes. --- benchmarks/.gitignore | 2 +- benchmarks/filtsmooth.py | 1 + benchmarks/ivpsolvers.py | 1 + benchmarks/linearsolvers.py | 1 + benchmarks/randprocs.py | 1 + .../adding_to_the_api_documentation.rst | 4 +-- .../creating_an_example_notebook.rst | 10 +++--- .../quadopt_example/_probsolve_qp.py | 2 +- docs/source/development/unit_testing.rst | 6 ++-- src/probnum/.gitignore | 2 +- src/probnum/_config.py | 3 +- src/probnum/conftest.py | 2 +- src/probnum/diffeq/_odesolution.py | 4 +-- src/probnum/diffeq/_probsolve_ivp.py | 1 - src/probnum/diffeq/odefilter/_odefilter.py | 2 -- .../diffeq/odefilter/approx_strategies/_ek.py | 1 + .../odefilter/init_routines/_interface.py | 1 - .../init_routines/_non_probabilistic_fit.py | 1 - .../diffeq/odefilter/init_routines/_stack.py | 1 - .../diffeq/odefilter/utils/_problem_utils.py | 1 + .../_wrapped_scipy_odesolution.py | 1 + .../scipy_wrapper/_wrapped_scipy_solver.py | 1 + .../perturbed/step/_perturbation_functions.py | 1 + .../diffeq/stepsize/_propose_firststep.py | 4 +-- src/probnum/filtsmooth/__init__.py | 10 +++--- .../filtsmooth/_timeseriesposterior.py | 5 ++- src/probnum/filtsmooth/gaussian/_kalman.py | 1 - .../filtsmooth/optim/_stopping_criterion.py | 1 + src/probnum/linalg/__init__.py | 1 + .../solvers/_probabilistic_linear_solver.py | 2 +- .../_linear_solver_belief_update.py | 5 +-- .../_matrix_based_linear_belief_update.py | 5 +-- ...etric_matrix_based_linear_belief_update.py | 1 + .../_projected_residual_belief_update.py | 1 + .../solvers/beliefs/_linear_system_belief.py | 4 +-- .../_linear_solver_information_op.py | 1 + .../linalg/solvers/information_ops/_matvec.py | 1 + .../information_ops/_projected_residual.py | 1 + src/probnum/linalg/solvers/matrixbased.py | 5 +-- .../solvers/policies/_linear_solver_policy.py | 1 + .../solvers/stopping_criteria/_maxiter.py | 1 + src/probnum/linops/_arithmetic.py | 11 ++++-- src/probnum/linops/_block.py | 1 + src/probnum/linops/_kronecker.py | 9 +++-- src/probnum/linops/_scaling.py | 2 +- src/probnum/linops/_utils.py | 1 + src/probnum/linops/_vectorize.py | 4 +-- src/probnum/problems/_problems.py | 7 ++-- src/probnum/problems/zoo/diffeq/__init__.py | 1 - .../problems/zoo/diffeq/_ivp_examples_jax.py | 6 ++-- .../problems/zoo/filtsmooth/__init__.py | 1 - .../zoo/filtsmooth/_filtsmooth_problems.py | 3 -- .../zoo/linalg/_random_linear_system.py | 4 +-- .../problems/zoo/linalg/_random_spd_matrix.py | 7 ++-- .../zoo/linalg/_suitesparse_matrix.py | 2 +- .../problems/zoo/quad/_emukit_problems.py | 10 ++---- .../zoo/quad/_quadproblems_gaussian.py | 4 +-- src/probnum/quad/__init__.py | 8 ++--- src/probnum/quad/_bayesquad.py | 11 +++--- src/probnum/quad/_utils.py | 6 ++-- .../quad/kernel_embeddings/_expquad_gauss.py | 4 +-- .../kernel_embeddings/_expquad_lebesgue.py | 10 +++--- .../kernel_embeddings/_matern_lebesgue.py | 1 - .../quad/solvers/_bayesian_quadrature.py | 7 +--- .../_integral_variance_reduction.py | 1 - .../_mutual_information.py | 1 - .../solvers/belief_updates/_belief_update.py | 4 +-- .../belief_updates/_standard_update.py | 6 ++-- .../initial_designs/_initial_design.py | 1 - .../solvers/initial_designs/_mc_design.py | 1 - .../policies/_max_aquisition_policy.py | 1 - .../stopping_criteria/_immediate_stop.py | 5 +-- .../_integral_variance_tol.py | 2 +- src/probnum/randprocs/__init__.py | 7 ++-- src/probnum/randprocs/covfuncs/__init__.py | 8 ++--- src/probnum/randprocs/covfuncs/_arithmetic.py | 1 + .../covfuncs/_covariance_function.py | 36 ++++++++++++------- .../covfuncs/_covariance_linear_operator.py | 6 ++-- src/probnum/randprocs/covfuncs/_matern.py | 3 +- src/probnum/randprocs/kernels.py | 1 + src/probnum/randprocs/markov/_transition.py | 16 ++++----- .../markov/continuous/_diffusions.py | 5 ++- .../randprocs/markov/continuous/_lti_sde.py | 1 + .../randprocs/markov/continuous/_mfd.py | 1 - .../markov/discrete/_linear_gaussian.py | 1 + .../markov/discrete/_lti_gaussian.py | 1 - .../markov/integrator/_integrator.py | 2 -- .../randprocs/markov/integrator/_ioup.py | 2 ++ .../randprocs/markov/integrator/_iwp.py | 1 + .../randprocs/markov/integrator/_matern.py | 2 ++ src/probnum/randvars/_categorical.py | 1 + src/probnum/randvars/_constant.py | 2 +- src/probnum/randvars/_normal.py | 5 +-- src/probnum/randvars/_random_variable.py | 12 ++++--- src/probnum/randvars/_scipy_stats.py | 2 +- src/probnum/randvars/_utils.py | 1 + src/probnum/typing.py | 28 +++++++++------ src/probnum/utils/linalg/_cholesky_updates.py | 5 ++- src/probnum/utils/linalg/_inner_product.py | 1 + tests/conftest.py | 5 +-- .../test_callbacks/test_discrete_callback.py | 1 - .../test_init_routines/test_init_routines.py | 1 - .../test_odefilter/test_odefilter.py | 1 - .../test_odefilter/test_odefilter_cases.py | 1 - .../test_odefilter/test_odefilter_special.py | 1 + .../test_utils/test_problem_utils.py | 1 - tests/test_filtsmooth/conftest.py | 1 - .../test_optim/test_stoppingcriterion.py | 1 - .../test_solvers/cases/belief_updates.py | 1 + .../test_solvers/cases/policies.py | 1 + tests/test_linalg/test_solvers/conftest.py | 1 + .../test_beliefs/test_linear_system_belief.py | 1 + .../test_policies/test_conjugate_gradient.py | 1 + .../test_linear_solver_policy.py | 1 + .../test_policies/test_random_unit_vector.py | 1 + .../test_symmetric.py | 1 + tests/test_linops/test_arithmetics.py | 22 +++++++----- .../test_linops/test_linop_decompositions.py | 10 +++--- .../test_diffeq/test_ivp_examples_jax.py | 24 ++++++++++++- .../test_zoo/test_quad/test_problems.py | 4 +-- .../test_quad/test_quadproblems_uniform.py | 2 +- tests/test_quad/test_bayesian_quadrature.py | 4 +-- tests/test_quad/test_bayesquad/test_bq.py | 5 +-- tests/test_quad/test_initial_designs.py | 1 - tests/test_quad/util.py | 1 + .../test_covfuncs/test_arithmetic.py | 1 + .../test_randprocs/test_covfuncs/test_call.py | 7 ++-- .../test_continuous/test_diffusions.py | 6 ++-- .../test_continuous/test_linear_sde.py | 6 ++-- .../test_markov/test_integrator/test_ioup.py | 1 - .../test_integrator/test_matern.py | 1 - .../test_randvars/test_arithmetic/conftest.py | 1 + .../test_arithmetic/test_constant.py | 1 + tests/test_randvars/test_categorical.py | 1 - tests/test_randvars/test_constant.py | 1 + tests/test_randvars/test_normal.py | 1 + tests/test_randvars/test_random_variable.py | 4 +-- tests/testing/statistics.py | 1 - 138 files changed, 289 insertions(+), 230 deletions(-) diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index 3456f5d8d..b8a10c5c5 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -1,2 +1,2 @@ .asv/ -probnum/ \ No newline at end of file +probnum/ diff --git a/benchmarks/filtsmooth.py b/benchmarks/filtsmooth.py index b6daab428..217e8c5e6 100644 --- a/benchmarks/filtsmooth.py +++ b/benchmarks/filtsmooth.py @@ -1,4 +1,5 @@ """Benchmarks for Gaussian filtering.""" + import functools import numpy as np diff --git a/benchmarks/ivpsolvers.py b/benchmarks/ivpsolvers.py index 586fbd4f6..c819c7c26 100644 --- a/benchmarks/ivpsolvers.py +++ b/benchmarks/ivpsolvers.py @@ -1,4 +1,5 @@ """Benchmarks for probabilistic IVP solvers.""" + import numpy as np from probnum.diffeq import probsolve_ivp diff --git a/benchmarks/linearsolvers.py b/benchmarks/linearsolvers.py index f79befb4e..2354038ad 100644 --- a/benchmarks/linearsolvers.py +++ b/benchmarks/linearsolvers.py @@ -1,4 +1,5 @@ """Benchmarks for linear solvers.""" + import numpy as np from probnum import linops, problems, randvars diff --git a/benchmarks/randprocs.py b/benchmarks/randprocs.py index 1db924c2d..445aaf4e1 100644 --- a/benchmarks/randprocs.py +++ b/benchmarks/randprocs.py @@ -1,4 +1,5 @@ """Benchmarks for random processes.""" + import numpy as np import scipy.stats diff --git a/docs/source/development/adding_to_the_api_documentation.rst b/docs/source/development/adding_to_the_api_documentation.rst index 98789425c..df4f23b94 100644 --- a/docs/source/development/adding_to_the_api_documentation.rst +++ b/docs/source/development/adding_to_the_api_documentation.rst @@ -17,7 +17,7 @@ detail its functionality. This package uses the `NumPy docstring format `__. As a rule, all functions which are exposed to the user *must* have appropriate docstrings. Below is an example of a docstring for a -probabilistic numerical method +probabilistic numerical method named ``problinsolve`` defined in ``_problinsolve.py`` in the ``linalg`` subpackage. .. literalinclude:: ../../../src/probnum/linalg/_problinsolve.py @@ -103,7 +103,7 @@ documentation. You can configure Sphinx itself or its extensions in the .. code:: ipython3 from IPython.display import Image - + display(Image(filename="../assets/img/developer_guides/sphinx_logo.png", embed=True)) diff --git a/docs/source/development/creating_an_example_notebook.rst b/docs/source/development/creating_an_example_notebook.rst index d38f5e44e..1bba623f7 100644 --- a/docs/source/development/creating_an_example_notebook.rst +++ b/docs/source/development/creating_an_example_notebook.rst @@ -10,8 +10,8 @@ follow the instructions below. .. code:: ipython3 from IPython.display import Image - - display(Image(url='https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/1200px-Jupyter_logo.svg.png', + + display(Image(url='https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/1200px-Jupyter_logo.svg.png', width=250, embed=True)) @@ -44,12 +44,12 @@ of the notebook should contain the following code snippet. # Make inline plots vector graphics instead of raster graphics %matplotlib inline from IPython.display import set_matplotlib_formats - + set_matplotlib_formats("pdf", "svg") - + # Plotting import matplotlib.pyplot as plt - + plt.style.use("../probnum.mplstyle") This snippet defines the style of plots generated by Matplotlib. For diff --git a/docs/source/development/quadopt_example/_probsolve_qp.py b/docs/source/development/quadopt_example/_probsolve_qp.py index 064f13ed9..f211689af 100644 --- a/docs/source/development/quadopt_example/_probsolve_qp.py +++ b/docs/source/development/quadopt_example/_probsolve_qp.py @@ -133,7 +133,7 @@ def probsolve_qp( def _choose_prior( - fun_params0: Union[randvars.RandomVariable, np.ndarray, None] + fun_params0: Union[randvars.RandomVariable, np.ndarray, None], ) -> randvars.RandomVariable: """Initialize the prior distribution over the parameters. diff --git a/docs/source/development/unit_testing.rst b/docs/source/development/unit_testing.rst index f6e6da081..e12c90134 100644 --- a/docs/source/development/unit_testing.rst +++ b/docs/source/development/unit_testing.rst @@ -60,7 +60,7 @@ check out the following guides: .. code:: ipython3 from IPython.display import Image - + display(Image(url='https://code.visualstudio.com/assets/docs/python/testing/test-results.png', embed=True)) @@ -86,7 +86,7 @@ test. Here is a simple example. def add(x, y): return x + y - + def test_symmetric(): assert add(3, 5) == add(5, 3) @@ -96,7 +96,7 @@ You can do so by parametrizing tests via a decorator. .. code:: ipython3 import pytest - + @pytest.mark.parametrize("x,y", [(3, 5), (-1, 1), (0, 1.2)]) def test_symmetric(x, y): assert add(x, y) == add(y, x) diff --git a/src/probnum/.gitignore b/src/probnum/.gitignore index f528fc441..050cda3ca 100644 --- a/src/probnum/.gitignore +++ b/src/probnum/.gitignore @@ -1 +1 @@ -_version.py \ No newline at end of file +_version.py diff --git a/src/probnum/_config.py b/src/probnum/_config.py index 098ab9fed..e60aad4b6 100644 --- a/src/probnum/_config.py +++ b/src/probnum/_config.py @@ -1,4 +1,4 @@ -"""ProbNum library configuration""" +"""ProbNum library configuration.""" import contextlib import dataclasses @@ -165,6 +165,7 @@ def register(self, key: str, default_value: Any, description: str) -> None: ), ] + # ... and register the default configuration options. def _register_defaults(): for key, default_value, descr in _DEFAULT_CONFIG_OPTIONS: diff --git a/src/probnum/conftest.py b/src/probnum/conftest.py index 68c279ef7..94df8ad12 100644 --- a/src/probnum/conftest.py +++ b/src/probnum/conftest.py @@ -9,7 +9,7 @@ @pytest.fixture(autouse=True) def autoimport_packages(doctest_namespace): # pylint: disable=missing-any-param-doc """This fixture 'imports' standard packages automatically in order to avoid - boilerplate code in doctests""" + boilerplate code in doctests.""" doctest_namespace["pn"] = pn doctest_namespace["np"] = np diff --git a/src/probnum/diffeq/_odesolution.py b/src/probnum/diffeq/_odesolution.py index 38f8a69e8..a3b1f3501 100644 --- a/src/probnum/diffeq/_odesolution.py +++ b/src/probnum/diffeq/_odesolution.py @@ -2,8 +2,8 @@ This object is returned by ODESolver.solve(). -Provides dense output (by being callable), is sliceable, -and collects the time-grid as well as the discrete-time solution. +Provides dense output (by being callable), is sliceable, and collects the time-grid as +well as the discrete-time solution. """ from typing import Optional diff --git a/src/probnum/diffeq/_probsolve_ivp.py b/src/probnum/diffeq/_probsolve_ivp.py index c0f3c733b..ded3a2de6 100644 --- a/src/probnum/diffeq/_probsolve_ivp.py +++ b/src/probnum/diffeq/_probsolve_ivp.py @@ -267,7 +267,6 @@ def probsolve_ivp( [0.97] [0.98] [0.99]] - """ # Create IVP object diff --git a/src/probnum/diffeq/odefilter/_odefilter.py b/src/probnum/diffeq/odefilter/_odefilter.py index 986173de0..d0cbc37c9 100644 --- a/src/probnum/diffeq/odefilter/_odefilter.py +++ b/src/probnum/diffeq/odefilter/_odefilter.py @@ -56,7 +56,6 @@ class ODEFilter(_odesolver.ODESolver): .. [2] Bosch, N., and Hennig, P., and Tronarp, F.. Calibrated adaptive probabilistic ODE solvers. 2021. - """ def __init__( @@ -196,7 +195,6 @@ def attempt_step(self, state, dt): 5. With the results of either 4.1. or 4.2. (which both return a predicted RV and a measured RV), we finally compute the Kalman update and return the result. Recall that the error estimate has been computed in the third step. - """ # Read off system matrices; required for calibration / error estimation diff --git a/src/probnum/diffeq/odefilter/approx_strategies/_ek.py b/src/probnum/diffeq/odefilter/approx_strategies/_ek.py index 353ad0e49..5b7107d78 100644 --- a/src/probnum/diffeq/odefilter/approx_strategies/_ek.py +++ b/src/probnum/diffeq/odefilter/approx_strategies/_ek.py @@ -2,6 +2,7 @@ Make an intractable information operator tractable with local linearization. """ + from typing import Optional import numpy as np diff --git a/src/probnum/diffeq/odefilter/init_routines/_interface.py b/src/probnum/diffeq/odefilter/init_routines/_interface.py index dc6978722..cc612ff11 100644 --- a/src/probnum/diffeq/odefilter/init_routines/_interface.py +++ b/src/probnum/diffeq/odefilter/init_routines/_interface.py @@ -1,6 +1,5 @@ """Interface for initialization routines.""" - import abc from probnum import problems, randprocs, randvars diff --git a/src/probnum/diffeq/odefilter/init_routines/_non_probabilistic_fit.py b/src/probnum/diffeq/odefilter/init_routines/_non_probabilistic_fit.py index 6dd2a8a11..3e8bcca0e 100644 --- a/src/probnum/diffeq/odefilter/init_routines/_non_probabilistic_fit.py +++ b/src/probnum/diffeq/odefilter/init_routines/_non_probabilistic_fit.py @@ -1,7 +1,6 @@ """Initialization routines based on fitting the prior to (a few steps of a) non- probabilistc solver.""" - from typing import Optional import numpy as np diff --git a/src/probnum/diffeq/odefilter/init_routines/_stack.py b/src/probnum/diffeq/odefilter/init_routines/_stack.py index 2bb00dd14..74b41eafe 100644 --- a/src/probnum/diffeq/odefilter/init_routines/_stack.py +++ b/src/probnum/diffeq/odefilter/init_routines/_stack.py @@ -1,6 +1,5 @@ """Stacking-based initialization routines.""" - import numpy as np from probnum import problems, randprocs, randvars diff --git a/src/probnum/diffeq/odefilter/utils/_problem_utils.py b/src/probnum/diffeq/odefilter/utils/_problem_utils.py index a396b5646..c58fc73c4 100644 --- a/src/probnum/diffeq/odefilter/utils/_problem_utils.py +++ b/src/probnum/diffeq/odefilter/utils/_problem_utils.py @@ -10,6 +10,7 @@ __all__ = ["ivp_to_regression_problem"] + # The ODE information operator is not optional, because in order to create it # one needs to know the order of the algorithm that is desired # (i.e. num_prior_derivatives). Since this is a weird input for the function, it seems diff --git a/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_odesolution.py b/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_odesolution.py index 768bf77f7..429642ffa 100644 --- a/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_odesolution.py +++ b/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_odesolution.py @@ -1,4 +1,5 @@ """Make a ProbNum ODE solution out of a scipy ODE solution.""" + import numpy as np from scipy.integrate._ivp.common import OdeSolution diff --git a/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_solver.py b/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_solver.py index 6f2dd88be..dcab8e4eb 100644 --- a/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_solver.py +++ b/src/probnum/diffeq/perturbed/scipy_wrapper/_wrapped_scipy_solver.py @@ -3,6 +3,7 @@ Dense-output can not be used for DOP853, if you use other RK-methods, make sure, that the current implementation works for them. """ + import numpy as np from scipy.integrate._ivp import rk from scipy.integrate._ivp.common import OdeSolution diff --git a/src/probnum/diffeq/perturbed/step/_perturbation_functions.py b/src/probnum/diffeq/perturbed/step/_perturbation_functions.py index fe0a7b44b..9a50ff8d9 100644 --- a/src/probnum/diffeq/perturbed/step/_perturbation_functions.py +++ b/src/probnum/diffeq/perturbed/step/_perturbation_functions.py @@ -1,4 +1,5 @@ """Perturbation functions to perturb the stepsize.""" + from typing import Optional, Union import numpy as np diff --git a/src/probnum/diffeq/stepsize/_propose_firststep.py b/src/probnum/diffeq/stepsize/_propose_firststep.py index 8b5f8b515..0357a6c3d 100644 --- a/src/probnum/diffeq/stepsize/_propose_firststep.py +++ b/src/probnum/diffeq/stepsize/_propose_firststep.py @@ -6,8 +6,8 @@ def propose_firststep(ivp): """Propose a suitable first step-size that can be taken by an ODE solver. - This function implements a lazy version of the algorithm on p. 169 - of Hairer, Wanner, Norsett. + This function implements a lazy version of the algorithm on p. 169 of Hairer, + Wanner, Norsett. """ norm_y0 = np.linalg.norm(ivp.y0) norm_dy0 = np.linalg.norm(ivp.f(ivp.t0, ivp.y0)) diff --git a/src/probnum/filtsmooth/__init__.py b/src/probnum/filtsmooth/__init__.py index 7d9393667..00785046b 100644 --- a/src/probnum/filtsmooth/__init__.py +++ b/src/probnum/filtsmooth/__init__.py @@ -1,11 +1,11 @@ """Bayesian Filtering and Smoothing. -This package provides different kinds of Bayesian filters and smoothers -which estimate the distribution over observed and hidden variables in a -sequential model. The two operations differ by what information they -use. Filtering considers all observations up to a given point, while -smoothing takes the entire set of observations into account. +This package provides different kinds of Bayesian filters and smoothers which estimate +the distribution over observed and hidden variables in a sequential model. The two +operations differ by what information they use. Filtering considers all observations up +to a given point, while smoothing takes the entire set of observations into account. """ + from . import gaussian, particle, utils from ._bayesfiltsmooth import BayesFiltSmooth from ._kalman_filter_smoother import filter_kalman, smooth_rts diff --git a/src/probnum/filtsmooth/_timeseriesposterior.py b/src/probnum/filtsmooth/_timeseriesposterior.py index 11bf1ce42..09a7e876f 100644 --- a/src/probnum/filtsmooth/_timeseriesposterior.py +++ b/src/probnum/filtsmooth/_timeseriesposterior.py @@ -13,9 +13,8 @@ DenseOutputValueType = Union[randvars.RandomVariable, randvars._RandomVariableList] """Output type of interpolation. -Dense evaluation of a TimeSeriesPosterior returns a RandomVariable -if evaluated at a single location, -and a _RandomVariableList if evaluated at an array of locations. +Dense evaluation of a TimeSeriesPosterior returns a RandomVariable if evaluated at a +single location, and a _RandomVariableList if evaluated at an array of locations. """ diff --git a/src/probnum/filtsmooth/gaussian/_kalman.py b/src/probnum/filtsmooth/gaussian/_kalman.py index 45869e4e5..67694eb69 100644 --- a/src/probnum/filtsmooth/gaussian/_kalman.py +++ b/src/probnum/filtsmooth/gaussian/_kalman.py @@ -1,6 +1,5 @@ """Gaussian filtering and smoothing.""" - from typing import Iterable, Optional, Union import numpy as np diff --git a/src/probnum/filtsmooth/optim/_stopping_criterion.py b/src/probnum/filtsmooth/optim/_stopping_criterion.py index 491e6305f..d312cb832 100644 --- a/src/probnum/filtsmooth/optim/_stopping_criterion.py +++ b/src/probnum/filtsmooth/optim/_stopping_criterion.py @@ -1,4 +1,5 @@ """Stopping criteria for iterated filtering and smoothing.""" + import numpy as np from probnum import StoppingCriterion diff --git a/src/probnum/linalg/__init__.py b/src/probnum/linalg/__init__.py index bf8d78691..d4d88003c 100644 --- a/src/probnum/linalg/__init__.py +++ b/src/probnum/linalg/__init__.py @@ -3,6 +3,7 @@ This package implements probabilistic numerical methods for the solution of problems arising in linear algebra, such as the solution of linear systems :math:`Ax=b`. """ + from probnum.linalg._bayescg import bayescg from probnum.linalg._problinsolve import problinsolve diff --git a/src/probnum/linalg/solvers/_probabilistic_linear_solver.py b/src/probnum/linalg/solvers/_probabilistic_linear_solver.py index 0c93aaf3e..48b6dccfb 100644 --- a/src/probnum/linalg/solvers/_probabilistic_linear_solver.py +++ b/src/probnum/linalg/solvers/_probabilistic_linear_solver.py @@ -116,7 +116,7 @@ class ProbabilisticLinearSolver( Solve the linear system using the custom solver. >>> belief, solver_state = pls.solve(prior=prior, problem=linsys) - >>> np.linalg.norm(linsys.A @ belief.x.mean - linsys.b) / np.linalg.norm(linsys.b) + >>> (np.linalg.norm(linsys.A @ belief.x.mean - linsys.b) / np.linalg.norm(linsys.b)).item() 7.1886e-06 """ diff --git a/src/probnum/linalg/solvers/belief_updates/_linear_solver_belief_update.py b/src/probnum/linalg/solvers/belief_updates/_linear_solver_belief_update.py index a820f87e1..5f127d45d 100644 --- a/src/probnum/linalg/solvers/belief_updates/_linear_solver_belief_update.py +++ b/src/probnum/linalg/solvers/belief_updates/_linear_solver_belief_update.py @@ -3,6 +3,7 @@ Class defining how a belief over quantities of interest of a linear system is updated given information about the problem. """ + import abc import probnum # pylint: disable="unused-import" @@ -12,8 +13,8 @@ class LinearSolverBeliefUpdate(abc.ABC): r"""Belief update for the quantities of interest of a linear system. - Given a solver state containing information about the linear system collected - in the current step, update the belief about the quantities of interest. + Given a solver state containing information about the linear system collected in the + current step, update the belief about the quantities of interest. """ @abc.abstractmethod diff --git a/src/probnum/linalg/solvers/belief_updates/matrix_based/_matrix_based_linear_belief_update.py b/src/probnum/linalg/solvers/belief_updates/matrix_based/_matrix_based_linear_belief_update.py index 0dad566d2..1905b9036 100644 --- a/src/probnum/linalg/solvers/belief_updates/matrix_based/_matrix_based_linear_belief_update.py +++ b/src/probnum/linalg/solvers/belief_updates/matrix_based/_matrix_based_linear_belief_update.py @@ -1,5 +1,6 @@ """Belief update in a matrix-based inference view where the information is given by matrix-vector multiplication.""" + import numpy as np import probnum # pylint: disable="unused-import" @@ -10,8 +11,8 @@ class MatrixBasedLinearBeliefUpdate(LinearSolverBeliefUpdate): - r"""Gaussian belief update in a matrix-based inference framework assuming - linear information. + r"""Gaussian belief update in a matrix-based inference framework assuming linear + information. Updates the belief over the quantities of interest of a linear system :math:`Ax=b` given matrix-variate Gaussian beliefs with Kronecker covariance structure and diff --git a/src/probnum/linalg/solvers/belief_updates/matrix_based/_symmetric_matrix_based_linear_belief_update.py b/src/probnum/linalg/solvers/belief_updates/matrix_based/_symmetric_matrix_based_linear_belief_update.py index 94d239eee..26f01c35e 100644 --- a/src/probnum/linalg/solvers/belief_updates/matrix_based/_symmetric_matrix_based_linear_belief_update.py +++ b/src/probnum/linalg/solvers/belief_updates/matrix_based/_symmetric_matrix_based_linear_belief_update.py @@ -1,5 +1,6 @@ """Belief update in a matrix-based inference view assuming symmetry where the information is given by matrix-vector multiplication.""" + import numpy as np import probnum # pylint: disable="unused-import" diff --git a/src/probnum/linalg/solvers/belief_updates/solution_based/_projected_residual_belief_update.py b/src/probnum/linalg/solvers/belief_updates/solution_based/_projected_residual_belief_update.py index 1d6a7637f..8b69475cb 100644 --- a/src/probnum/linalg/solvers/belief_updates/solution_based/_projected_residual_belief_update.py +++ b/src/probnum/linalg/solvers/belief_updates/solution_based/_projected_residual_belief_update.py @@ -1,5 +1,6 @@ """Belief update in a solution-based inference view where the information is given by projecting the current residual to a subspace.""" + import numpy as np import probnum # pylint: disable="unused-import" diff --git a/src/probnum/linalg/solvers/beliefs/_linear_system_belief.py b/src/probnum/linalg/solvers/beliefs/_linear_system_belief.py index 62be3da21..636e6bd4e 100644 --- a/src/probnum/linalg/solvers/beliefs/_linear_system_belief.py +++ b/src/probnum/linalg/solvers/beliefs/_linear_system_belief.py @@ -1,7 +1,7 @@ """Linear system belief. -Class defining a belief about the quantities of interest of a linear system such -as its solution or the matrix inverse and any associated hyperparameters. +Class defining a belief about the quantities of interest of a linear system such as its +solution or the matrix inverse and any associated hyperparameters. """ from functools import cached_property diff --git a/src/probnum/linalg/solvers/information_ops/_linear_solver_information_op.py b/src/probnum/linalg/solvers/information_ops/_linear_solver_information_op.py index 51cab9c34..a08eea74a 100644 --- a/src/probnum/linalg/solvers/information_ops/_linear_solver_information_op.py +++ b/src/probnum/linalg/solvers/information_ops/_linear_solver_information_op.py @@ -1,4 +1,5 @@ """Base class for linear solver information operators.""" + import abc import numpy as np diff --git a/src/probnum/linalg/solvers/information_ops/_matvec.py b/src/probnum/linalg/solvers/information_ops/_matvec.py index 430f21889..b84adc700 100644 --- a/src/probnum/linalg/solvers/information_ops/_matvec.py +++ b/src/probnum/linalg/solvers/information_ops/_matvec.py @@ -1,4 +1,5 @@ """Information operator returning a matrix-vector product with the matrix.""" + import numpy as np import probnum # pylint: disable="unused-import" diff --git a/src/probnum/linalg/solvers/information_ops/_projected_residual.py b/src/probnum/linalg/solvers/information_ops/_projected_residual.py index 493265f7b..78edc3cb6 100644 --- a/src/probnum/linalg/solvers/information_ops/_projected_residual.py +++ b/src/probnum/linalg/solvers/information_ops/_projected_residual.py @@ -1,4 +1,5 @@ """Information operator returning a projection of the right-hand-side.""" + import numpy as np import probnum # pylint: disable="unused-import" diff --git a/src/probnum/linalg/solvers/matrixbased.py b/src/probnum/linalg/solvers/matrixbased.py index cbc5f36c7..30921736d 100644 --- a/src/probnum/linalg/solvers/matrixbased.py +++ b/src/probnum/linalg/solvers/matrixbased.py @@ -1,8 +1,9 @@ """Matrix-based probabilistic linear solvers. -Implementations of matrix-based linear solvers which perform inference -on the matrix or its inverse given linear observations. +Implementations of matrix-based linear solvers which perform inference on the matrix or +its inverse given linear observations. """ + import abc import warnings diff --git a/src/probnum/linalg/solvers/policies/_linear_solver_policy.py b/src/probnum/linalg/solvers/policies/_linear_solver_policy.py index 43197b49b..bc60b8f10 100644 --- a/src/probnum/linalg/solvers/policies/_linear_solver_policy.py +++ b/src/probnum/linalg/solvers/policies/_linear_solver_policy.py @@ -1,4 +1,5 @@ """Base class for policies of probabilistic linear solvers returning actions.""" + import abc from typing import Optional diff --git a/src/probnum/linalg/solvers/stopping_criteria/_maxiter.py b/src/probnum/linalg/solvers/stopping_criteria/_maxiter.py index 8ceafbdab..de43a1e91 100644 --- a/src/probnum/linalg/solvers/stopping_criteria/_maxiter.py +++ b/src/probnum/linalg/solvers/stopping_criteria/_maxiter.py @@ -1,4 +1,5 @@ """Stopping criterion based on a maximum number of iterations.""" + from typing import Optional import probnum # pylint: disable="unused-import" diff --git a/src/probnum/linops/_arithmetic.py b/src/probnum/linops/_arithmetic.py index 00ec028a6..0883bd314 100644 --- a/src/probnum/linops/_arithmetic.py +++ b/src/probnum/linops/_arithmetic.py @@ -1,4 +1,5 @@ """Linear operator arithmetic.""" + from typing import Any, Callable, Dict, Optional, Tuple, Union import numpy as np @@ -97,6 +98,7 @@ def matmul(op1: LinearOperator, op2: LinearOperator) -> LinearOperator: # Fill Arithmetics Registries ######################################################################################## + # Scaling def _mul_scalar_scaling(scalar: ScalarLike, scaling: Scaling) -> Scaling: if scaling.is_isotropic: @@ -119,6 +121,7 @@ def _mul_scaling_scalar(scaling: Scaling, scalar: ScalarLike) -> Scaling: _mul_fns[(Scaling, Scaling)] = Scaling._mul_scaling _matmul_fns[(Scaling, Scaling)] = Scaling._matmul_scaling + # ScaledLinearOperator def _matmul_scaled_op(scaled, anylinop): return scaled._scalar * (scaled._linop @ anylinop) @@ -233,9 +236,9 @@ def _mul_idkronecker_scalar( ) -_matmul_fns[ - (IdentityKronecker, IdentityKronecker) -] = IdentityKronecker._matmul_idkronecker +_matmul_fns[(IdentityKronecker, IdentityKronecker)] = ( + IdentityKronecker._matmul_idkronecker +) _add_fns[(IdentityKronecker, IdentityKronecker)] = IdentityKronecker._add_idkronecker _sub_fns[(IdentityKronecker, IdentityKronecker)] = IdentityKronecker._sub_idkronecker @@ -247,6 +250,7 @@ def _mul_idkronecker_scalar( _matmul_fns[(Kronecker, IdentityKronecker)] = Kronecker._matmul_kronecker _matmul_fns[(IdentityKronecker, Kronecker)] = Kronecker._matmul_kronecker + # Matrix def _matmul_scaling_matrix(scaling: Scaling, matrix: Matrix) -> Matrix: return Matrix(A=np.multiply(scaling.factors[:, np.newaxis], matrix.A)) @@ -330,6 +334,7 @@ def _matmul_selection_embedding( _matmul_fns[(Selection, Embedding)] = _matmul_selection_embedding # Embedding @ Selection would be Projection + # Zero def _matmul_zero_anylinop(z: Zero, op: LinearOperator) -> Zero: if z.shape[1] != op.shape[0]: diff --git a/src/probnum/linops/_block.py b/src/probnum/linops/_block.py index 3addc77d8..b1b8d0e92 100644 --- a/src/probnum/linops/_block.py +++ b/src/probnum/linops/_block.py @@ -1,4 +1,5 @@ """Operators with block structure.""" + from __future__ import annotations import functools diff --git a/src/probnum/linops/_kronecker.py b/src/probnum/linops/_kronecker.py index f62598c13..e02692253 100644 --- a/src/probnum/linops/_kronecker.py +++ b/src/probnum/linops/_kronecker.py @@ -1,4 +1,5 @@ """Operators of Kronecker-type or related.""" + from __future__ import annotations from typing import Optional, Union @@ -252,9 +253,8 @@ def _kronecker_matmul( B: _linear_operator.LinearOperator, x: np.ndarray, ): - """Efficient multiplication via (A (x) B)vec(X) = vec(AXB^T) where vec is the - row-wise vectorization operator. - """ + """Efficient multiplication via (A (x) B)vec(X) = vec(AXB^T) where vec is the row- + wise vectorization operator.""" # vec(X) -> X, i.e. reshape into stack of matrices y = np.swapaxes(x, -2, -1) @@ -374,8 +374,7 @@ def _astype( def _matmul(self, x: np.ndarray) -> np.ndarray: """Efficient multiplication via (A (x)_s B)vec(X) = 1/2 vec(BXA^T + AXB^T) where - vec is the column-wise normalized symmetric stacking operator. - """ + vec is the column-wise normalized symmetric stacking operator.""" if self.identical_factors: return _kronecker_matmul(self.A, self.A, x) diff --git a/src/probnum/linops/_scaling.py b/src/probnum/linops/_scaling.py index 038b5665f..1140dc7fd 100644 --- a/src/probnum/linops/_scaling.py +++ b/src/probnum/linops/_scaling.py @@ -1,4 +1,5 @@ """Scaling linear operator.""" + from __future__ import annotations from typing import Optional, Union @@ -35,7 +36,6 @@ class Scaling(_linear_operator.LambdaLinearOperator): Shape of the linear operator. dtype : Data type of the linear operator. - """ def __init__( diff --git a/src/probnum/linops/_utils.py b/src/probnum/linops/_utils.py index b9689ce52..1485c914d 100644 --- a/src/probnum/linops/_utils.py +++ b/src/probnum/linops/_utils.py @@ -1,4 +1,5 @@ """Utility functions for linear operators.""" + from __future__ import annotations import numpy as np diff --git a/src/probnum/linops/_vectorize.py b/src/probnum/linops/_vectorize.py index bdf88e815..5a9dc0b42 100644 --- a/src/probnum/linops/_vectorize.py +++ b/src/probnum/linops/_vectorize.py @@ -30,7 +30,7 @@ def vectorize_matmat( """ def _vectorize_matmat( - matmat: Callable[[np.ndarray], np.ndarray] + matmat: Callable[[np.ndarray], np.ndarray], ) -> Callable[[np.ndarray], np.ndarray]: np_vectorize_obj = np.vectorize( matmat, @@ -71,7 +71,7 @@ def vectorize_matvec( """ def _vectorize_matvec( - matvec: Callable[[np.ndarray], np.ndarray] + matvec: Callable[[np.ndarray], np.ndarray], ) -> Callable[[np.ndarray], np.ndarray]: @functools.wraps(matvec) def vectorized_matvec(*args) -> np.ndarray: diff --git a/src/probnum/problems/_problems.py b/src/probnum/problems/_problems.py index eb86ef208..329798da9 100644 --- a/src/probnum/problems/_problems.py +++ b/src/probnum/problems/_problems.py @@ -1,4 +1,5 @@ """Definitions of problems currently solved by probabilistic numerical methods.""" + from __future__ import annotations from collections import abc @@ -158,7 +159,7 @@ class InitialValueProblem: >>> ivp = InitialValueProblem(f, t0=0., tmax=3., y0=0.1) >>> ivp.t0, ivp.tmax, ivp.y0 (0.0, 3.0, 0.1) - >>> np.round(ivp.f(ivp.t0, ivp.y0), 2) + >>> np.round(ivp.f(ivp.t0, ivp.y0), 2).item() 0.09 """ @@ -252,11 +253,11 @@ class QuadratureProblem: >>> >>> measure1d = LebesgueMeasure(domain=(0, 1), input_dim=1) >>> qp1d = QuadratureProblem(fun, measure=measure1d, solution=1/3) - >>> np.round(qp1d.fun(np.array([[0.2]]))[0], 2) + >>> np.round(qp1d.fun(np.array([[0.2]]))[0], 2).item() 0.04 >>> measure2d = LebesgueMeasure(domain=(0, 1), input_dim=2) >>> qp2d = QuadratureProblem(fun, measure=measure2d, solution=None) - >>> np.round(qp2d.fun(np.array([[0.2, 0.2]]))[0], 2) + >>> np.round(qp2d.fun(np.array([[0.2, 0.2]]))[0], 2).item() 0.08 """ diff --git a/src/probnum/problems/zoo/diffeq/__init__.py b/src/probnum/problems/zoo/diffeq/__init__.py index 71e1f8c33..22838e9ad 100644 --- a/src/probnum/problems/zoo/diffeq/__init__.py +++ b/src/probnum/problems/zoo/diffeq/__init__.py @@ -1,6 +1,5 @@ """Test problems involving ordinary differential equations.""" - from ._ivp_examples import ( fitzhughnagumo, logistic, diff --git a/src/probnum/problems/zoo/diffeq/_ivp_examples_jax.py b/src/probnum/problems/zoo/diffeq/_ivp_examples_jax.py index 5e3eb136a..b64f47a26 100644 --- a/src/probnum/problems/zoo/diffeq/_ivp_examples_jax.py +++ b/src/probnum/problems/zoo/diffeq/_ivp_examples_jax.py @@ -96,7 +96,7 @@ def _import_jax(): try: import jax - from jax.config import config + from jax import config import jax.numpy as jnp config.update("jax_enable_x64", True) @@ -107,8 +107,8 @@ def _import_jax(): def vanderpol_jax(t0=0.0, tmax=30, y0=None, params=1e1): - r"""Initial value problem (IVP) based on the Van der Pol Oscillator, - implemented in `jax`. + r"""Initial value problem (IVP) based on the Van der Pol Oscillator, implemented in + `jax`. This function implements the second-order Van-der-Pol Oscillator as a system of first-order ODEs. diff --git a/src/probnum/problems/zoo/filtsmooth/__init__.py b/src/probnum/problems/zoo/filtsmooth/__init__.py index 39b4065de..eb79c4716 100644 --- a/src/probnum/problems/zoo/filtsmooth/__init__.py +++ b/src/probnum/problems/zoo/filtsmooth/__init__.py @@ -1,6 +1,5 @@ """Exemplary state space model setups for Bayesian Filtering and Smoothing.""" - from ._filtsmooth_problems import ( benes_daum, car_tracking, diff --git a/src/probnum/problems/zoo/filtsmooth/_filtsmooth_problems.py b/src/probnum/problems/zoo/filtsmooth/_filtsmooth_problems.py index 3d0dbdf20..0b71d9891 100644 --- a/src/probnum/problems/zoo/filtsmooth/_filtsmooth_problems.py +++ b/src/probnum/problems/zoo/filtsmooth/_filtsmooth_problems.py @@ -92,7 +92,6 @@ def car_tracking( ---------- .. [1] Särkkä, Simo. Bayesian Filtering and Smoothing. Cambridge University Press, 2013. - """ state_dim = 2 model_dim = state_dim * (num_prior_derivatives + 1) @@ -318,7 +317,6 @@ def pendulum( ---------- .. [1] Särkkä, Simo. Bayesian Filtering and Smoothing. Cambridge University Press, 2013. - """ # Graviational constant @@ -561,7 +559,6 @@ def logistic_ode( See Also -------- :py:class:`probnum.diffeq.ODEFilter` - """ if y0 is None: diff --git a/src/probnum/problems/zoo/linalg/_random_linear_system.py b/src/probnum/problems/zoo/linalg/_random_linear_system.py index b0f9baafe..a7a36094d 100644 --- a/src/probnum/problems/zoo/linalg/_random_linear_system.py +++ b/src/probnum/problems/zoo/linalg/_random_linear_system.py @@ -1,4 +1,5 @@ """Generate random linear systems as test problems.""" + from __future__ import annotations from typing import Any, Callable, Optional, Union @@ -60,9 +61,8 @@ def random_linear_system( >>> import scipy.stats >>> unitary_matrix = scipy.stats.unitary_group.rvs(dim=5, random_state=rng) >>> linsys_unitary = random_linear_system(rng, unitary_matrix) - >>> np.abs(np.linalg.det(linsys_unitary.A)) + >>> np.abs(np.linalg.det(linsys_unitary.A)).item() 1.0 - Linear system with random symmetric positive-definite matrix. >>> from probnum.problems.zoo.linalg import random_spd_matrix diff --git a/src/probnum/problems/zoo/linalg/_random_spd_matrix.py b/src/probnum/problems/zoo/linalg/_random_spd_matrix.py index f93e5a7c1..dc3df1bc6 100644 --- a/src/probnum/problems/zoo/linalg/_random_spd_matrix.py +++ b/src/probnum/problems/zoo/linalg/_random_spd_matrix.py @@ -1,4 +1,5 @@ """Random symmetric positive definite matrices.""" + from __future__ import annotations from typing import Sequence @@ -52,7 +53,7 @@ def random_spd_matrix( Check for symmetry and positive definiteness. - >>> np.all(mat == mat.T) + >>> np.all(mat == mat.T).item() True >>> np.linalg.eigvals(mat) array([ 8.09147328, 12.7635956 , 10.84504988, 10.73086331, 10.78143272]) @@ -135,8 +136,8 @@ def random_sparse_spd_matrix( >>> rng = np.random.default_rng(42) >>> sparsemat = random_sparse_spd_matrix(rng, dim=5, density=0.1) >>> sparsemat - <5x5 sparse matrix of type '' - with 9 stored elements in Compressed Sparse Row format> + >>> sparsemat.todense() matrix([[1. , 0. , 0.87273813, 0. , 0. ], [0. , 1. , 0. , 0. , 0. ], diff --git a/src/probnum/problems/zoo/linalg/_suitesparse_matrix.py b/src/probnum/problems/zoo/linalg/_suitesparse_matrix.py index e79fbca55..e789c17c8 100644 --- a/src/probnum/problems/zoo/linalg/_suitesparse_matrix.py +++ b/src/probnum/problems/zoo/linalg/_suitesparse_matrix.py @@ -48,7 +48,7 @@ def suitesparse_matrix( >>> ssmat = suitesparse_matrix(name="ash85", group="HB") >>> ssmat - >>> ssmat.trace() + >>> ssmat.trace().item() 85.0 """ # Get database index diff --git a/src/probnum/problems/zoo/quad/_emukit_problems.py b/src/probnum/problems/zoo/quad/_emukit_problems.py index 4d32666b4..0d68729c4 100644 --- a/src/probnum/problems/zoo/quad/_emukit_problems.py +++ b/src/probnum/problems/zoo/quad/_emukit_problems.py @@ -30,7 +30,6 @@ def hennig1d() -> QuadratureProblem: References ---------- .. [1] Emukit docs on `hennig1d `__. - """ # pylint: disable=line-too-long def fun(x): @@ -63,7 +62,6 @@ def hennig2d(c: Optional[np.ndarray] = None) -> QuadratureProblem: References ---------- .. [1] Emukit docs on `hennig2d `__ . - """ # pylint: disable=line-too-long solution = None @@ -86,8 +84,7 @@ def fun(x): def sombrero2d(w: Optional[FloatLike] = None) -> QuadratureProblem: - r"""The two-dimensional sombrero function integrated wrt the Lebesgue - measure. [1]_ + r"""The two-dimensional sombrero function integrated wrt the Lebesgue measure. [1]_ The integrand is @@ -110,7 +107,6 @@ def sombrero2d(w: Optional[FloatLike] = None) -> QuadratureProblem: References ---------- .. [1] Emukit docs on `sombrero2d `__ . - """ # pylint: disable=line-too-long solution = None @@ -136,8 +132,7 @@ def fun(x): def circulargaussian2d( m: Optional[FloatLike] = None, v: Optional[FloatLike] = None ) -> QuadratureProblem: - r"""The two-dimensional circular Gaussian integrated wrt the Lebesgue - measure. [1]_ + r"""The two-dimensional circular Gaussian integrated wrt the Lebesgue measure. [1]_ The integrand is @@ -164,7 +159,6 @@ def circulargaussian2d( References ---------- .. [1] Emukit docs on `circulargaussian2d `__ . - """ # pylint: disable=line-too-long _v = 1.0 diff --git a/src/probnum/problems/zoo/quad/_quadproblems_gaussian.py b/src/probnum/problems/zoo/quad/_quadproblems_gaussian.py index bf8533955..f61e27feb 100644 --- a/src/probnum/problems/zoo/quad/_quadproblems_gaussian.py +++ b/src/probnum/problems/zoo/quad/_quadproblems_gaussian.py @@ -130,8 +130,8 @@ def uniform_to_gaussian_quadprob( def sum_polynomials( dim: int, a: np.ndarray = None, b: np.ndarray = None, var: FloatLike = 1.0 ) -> QuadratureProblem: - r"""Quadrature problem with an integrand taking the form of a sum of polynomials - over :math:`\mathbb{R}^d`. + r"""Quadrature problem with an integrand taking the form of a sum of polynomials over + :math:`\mathbb{R}^d`. .. math:: f(x) = \sum_{j=0}^p \prod_{i=1}^dim a_{ji} x_i^{b_ji} diff --git a/src/probnum/quad/__init__.py b/src/probnum/quad/__init__.py index bbaf1426d..e647b5ead 100644 --- a/src/probnum/quad/__init__.py +++ b/src/probnum/quad/__init__.py @@ -1,9 +1,9 @@ """Quadrature / Numerical Integration of Functions. -This package implements Bayesian quadrature rules used for numerical -integration of functions on a given domain. Such methods integrate a -function by iteratively building a probabilistic model and adaptively -choosing points to evaluate the integrand based on said model. +This package implements Bayesian quadrature rules used for numerical integration of +functions on a given domain. Such methods integrate a function by iteratively building a +probabilistic model and adaptively choosing points to evaluate the integrand based on +said model. """ from . import integration_measures, kernel_embeddings, solvers diff --git a/src/probnum/quad/_bayesquad.py b/src/probnum/quad/_bayesquad.py index 73787e980..066b39e6a 100644 --- a/src/probnum/quad/_bayesquad.py +++ b/src/probnum/quad/_bayesquad.py @@ -33,10 +33,9 @@ def bayesquad( rng: Optional[np.random.Generator] = None, options: Optional[dict] = None, ) -> Tuple[Normal, BQIterInfo]: - r"""Infer the solution of the uni- or multivariate integral - :math:`\int_\Omega f(x) d \mu(x)` - on a hyper-rectangle :math:`\Omega = [a_1, b_1] \times \cdots \times [a_D, b_D]` - or :math:`\Omega = \mathbb{R}^D`. + r"""Infer the solution of the uni- or multivariate integral :math:`\int_\Omega f(x) d + \mu(x)` on a hyper-rectangle :math:`\Omega = [a_1, b_1] \times \cdots \times [a_D, + b_D]` or :math:`\Omega = \mathbb{R}^D`. Bayesian quadrature (BQ) infers integrals of the form @@ -318,8 +317,8 @@ def multilevel_bayesquad_from_data( domain: Optional[DomainLike] = None, options: Optional[dict] = None, ) -> Tuple[Normal, Tuple[BQIterInfo, ...]]: - r"""Infer the value of an integral from given sets of nodes and function - evaluations using a multilevel method. + r"""Infer the value of an integral from given sets of nodes and function evaluations + using a multilevel method. In multilevel Bayesian quadrature, the integral :math:`\int_\Omega f(x) d \mu(x)` is (approximately) decomposed as a telescoping sum over :math:`L+1` levels: diff --git a/src/probnum/quad/_utils.py b/src/probnum/quad/_utils.py index 5e682aec3..163bfaa05 100644 --- a/src/probnum/quad/_utils.py +++ b/src/probnum/quad/_utils.py @@ -1,4 +1,4 @@ -"""Helper functions for the quad package""" +"""Helper functions for the quad package.""" from __future__ import annotations @@ -14,8 +14,8 @@ def as_domain( domain: DomainLike, input_dim: Optional[IntLike] ) -> Tuple[DomainType, int]: - """Static method that converts the integration domain and input dimension to - the correct types. + """Static method that converts the integration domain and input dimension to the + correct types. If no ``input_dim`` is given, the dimension is inferred from the size of domain limits ``domain[0]`` and ``domain[1]``. These must be either scalars diff --git a/src/probnum/quad/kernel_embeddings/_expquad_gauss.py b/src/probnum/quad/kernel_embeddings/_expquad_gauss.py index 3e75ed6fb..6972f7045 100644 --- a/src/probnum/quad/kernel_embeddings/_expquad_gauss.py +++ b/src/probnum/quad/kernel_embeddings/_expquad_gauss.py @@ -13,7 +13,7 @@ def _kernel_mean_expquad_gauss( ) -> np.ndarray: r"""Kernel mean of the ExpQuad kernel with lenghtscale :math:`l` w.r.t. its first argument against a Gaussian measure with mean vector :math:`\mu` and covariance - matrix :math:`\Sigma`. The kernel mean is + matrix :math:`\Sigma`. The kernel mean is. .. math:: @@ -67,7 +67,7 @@ def _kernel_mean_expquad_gauss( def _kernel_variance_expquad_gauss(kernel: ExpQuad, measure: GaussianMeasure) -> float: r"""Kernel variance of the ExpQuad kernel with lenghtscale :math:`l` w.r.t. both arguments against a :math:`D`-dimensional Gaussian measure with mean vector - :math:`\mu` and covariance matrix :math:`\Sigma`. The kernel variance is + :math:`\mu` and covariance matrix :math:`\Sigma`. The kernel variance is. .. math:: diff --git a/src/probnum/quad/kernel_embeddings/_expquad_lebesgue.py b/src/probnum/quad/kernel_embeddings/_expquad_lebesgue.py index 0f6392154..36e83b9eb 100644 --- a/src/probnum/quad/kernel_embeddings/_expquad_lebesgue.py +++ b/src/probnum/quad/kernel_embeddings/_expquad_lebesgue.py @@ -14,9 +14,8 @@ def _kernel_mean_expquad_lebesgue( x: np.ndarray, kernel: ExpQuad, measure: LebesgueMeasure ) -> np.ndarray: r"""Kernel mean of the ExpQuad kernel with lenghtscale :math:`l` w.r.t. its first - argument against a Lebesgue measure on the hyper-rectangle - :math:`[a_1, b_1] \times \cdots \times [a_D, b_D]`. For unnormalised Lebesgue - measure the kernel mean is + argument against a Lebesgue measure on the hyper-rectangle :math:`[a_1, b_1] \times + \cdots \times [a_D, b_D]`. For unnormalised Lebesgue measure the kernel mean is. .. math:: @@ -64,9 +63,8 @@ def _kernel_variance_expquad_lebesgue( kernel: ExpQuad, measure: LebesgueMeasure ) -> float: r"""Kernel variance of the ExpQuad kernel with lenghtscale :math:`l` w.r.t. both - arguments against a Lebesgue measure on the hyper-rectangle - :math:`[a_1, b_1] \times \cdots \times [a_D, b_D]`. For unnormalised Lebesgue - measure the kernel variance is + arguments against a Lebesgue measure on the hyper-rectangle :math:`[a_1, b_1] \times + \cdots \times [a_D, b_D]`. For unnormalised Lebesgue measure the kernel variance is. .. math:: diff --git a/src/probnum/quad/kernel_embeddings/_matern_lebesgue.py b/src/probnum/quad/kernel_embeddings/_matern_lebesgue.py index 74558c92e..51ad2c71e 100644 --- a/src/probnum/quad/kernel_embeddings/_matern_lebesgue.py +++ b/src/probnum/quad/kernel_embeddings/_matern_lebesgue.py @@ -1,6 +1,5 @@ """Kernel embedding of Matern kernels with Lebesgue integration measure.""" - from typing import Tuple, Union import numpy as np diff --git a/src/probnum/quad/solvers/_bayesian_quadrature.py b/src/probnum/quad/solvers/_bayesian_quadrature.py index e9ea4ca82..f8525b9f2 100644 --- a/src/probnum/quad/solvers/_bayesian_quadrature.py +++ b/src/probnum/quad/solvers/_bayesian_quadrature.py @@ -74,8 +74,6 @@ class BayesianQuadrature: :func:`bayesquad_from_data ` : Computes the integral :math:`F` using a given dataset of nodes and function evaluations. - - """ def __init__( @@ -112,7 +110,6 @@ def from_problem( initial_design: Optional[str] = None, options: Optional[dict] = None, ) -> "BayesianQuadrature": - r"""Creates an instance of this class from a problem description. Parameters @@ -176,7 +173,6 @@ def from_problem( -------- :func:`bayesquad ` : For details on options for ``policy`` and ``initial_design``. - """ input_dim = int(input_dim) @@ -423,7 +419,6 @@ def integrate( may not obey the stopping criterion. For example, if stopping is induced via a maximum number of evaluations (``max_evals``) smaller than the batch size of the initial design, the initial design will be evaluated nevertheless. - """ # Check if integrand function is provided @@ -523,7 +518,7 @@ def integrate( info = BQIterInfo.from_bq_state(bq_state) # run loop - for (_, bq_state, info) in self.bq_iterator(bq_state, info, fun, rng): + for _, bq_state, info in self.bq_iterator(bq_state, info, fun, rng): pass return bq_state.integral_belief, bq_state, info diff --git a/src/probnum/quad/solvers/acquisition_functions/_integral_variance_reduction.py b/src/probnum/quad/solvers/acquisition_functions/_integral_variance_reduction.py index 0484aeb1c..78b11837a 100644 --- a/src/probnum/quad/solvers/acquisition_functions/_integral_variance_reduction.py +++ b/src/probnum/quad/solvers/acquisition_functions/_integral_variance_reduction.py @@ -39,7 +39,6 @@ class IntegralVarianceReduction(AcquisitionFunction): ---------- .. [1] Gessner et al. Active Multi-Information Source Bayesian Quadrature, *UAI*, 2019 - """ @property diff --git a/src/probnum/quad/solvers/acquisition_functions/_mutual_information.py b/src/probnum/quad/solvers/acquisition_functions/_mutual_information.py index dd237d772..d15ac82d3 100644 --- a/src/probnum/quad/solvers/acquisition_functions/_mutual_information.py +++ b/src/probnum/quad/solvers/acquisition_functions/_mutual_information.py @@ -33,7 +33,6 @@ class MutualInformation(AcquisitionFunction): ---------- .. [1] Gessner et al. Active Multi-Information Source Bayesian Quadrature, *UAI*, 2019 - """ @property diff --git a/src/probnum/quad/solvers/belief_updates/_belief_update.py b/src/probnum/quad/solvers/belief_updates/_belief_update.py index 290b537f6..3e161e079 100644 --- a/src/probnum/quad/solvers/belief_updates/_belief_update.py +++ b/src/probnum/quad/solvers/belief_updates/_belief_update.py @@ -60,7 +60,7 @@ def __call__( def compute_gram_cho_factor(self, gram: np.ndarray) -> Tuple[np.ndarray, bool]: """Compute the Cholesky decomposition of a positive-definite Gram matrix for use - in scipy.linalg.cho_solve + in scipy.linalg.cho_solve. .. warning:: Uses scipy.linalg.cho_factor. The returned matrix is only to be used in @@ -98,7 +98,6 @@ def gram_cho_solve( ------- solution : The solution ``x`` to the linear system ``gram x = z``. - """ return cho_solve(gram_cho_factor, z) @@ -122,6 +121,5 @@ def predict_integrand( *shape=(n_nodes,)* -- The means of the predictions. var_predictions : *shape=(n_nodes,)* -- The variances of the predictions. - """ raise NotImplementedError diff --git a/src/probnum/quad/solvers/belief_updates/_standard_update.py b/src/probnum/quad/solvers/belief_updates/_standard_update.py index c00674079..e5ae282ab 100644 --- a/src/probnum/quad/solvers/belief_updates/_standard_update.py +++ b/src/probnum/quad/solvers/belief_updates/_standard_update.py @@ -102,8 +102,10 @@ def __call__( # pylint: disable=no-self-use def _estimate_kernel(self, kernel: Kernel) -> Tuple[Kernel, bool]: - """Estimate the intrinsic kernel parameters. That is, all parameters except the - scale.""" + """Estimate the intrinsic kernel parameters. + + That is, all parameters except the scale. + """ new_kernel = kernel kernel_was_updated = False return new_kernel, kernel_was_updated diff --git a/src/probnum/quad/solvers/initial_designs/_initial_design.py b/src/probnum/quad/solvers/initial_designs/_initial_design.py index 0d4f45387..0f8a56fee 100644 --- a/src/probnum/quad/solvers/initial_designs/_initial_design.py +++ b/src/probnum/quad/solvers/initial_designs/_initial_design.py @@ -21,7 +21,6 @@ class InitialDesign(abc.ABC): The number of nodes to be designed. measure The integration measure. - """ def __init__(self, n_nodes: IntLike, measure: IntegrationMeasure) -> None: diff --git a/src/probnum/quad/solvers/initial_designs/_mc_design.py b/src/probnum/quad/solvers/initial_designs/_mc_design.py index e43d069df..043e9bbed 100644 --- a/src/probnum/quad/solvers/initial_designs/_mc_design.py +++ b/src/probnum/quad/solvers/initial_designs/_mc_design.py @@ -22,7 +22,6 @@ class MCDesign(InitialDesign): The number of nodes to be designed. measure The integration measure. - """ def __init__(self, n_nodes: IntLike, measure: IntegrationMeasure) -> None: diff --git a/src/probnum/quad/solvers/policies/_max_aquisition_policy.py b/src/probnum/quad/solvers/policies/_max_aquisition_policy.py index 83cf6d8b0..f0cdaea98 100644 --- a/src/probnum/quad/solvers/policies/_max_aquisition_policy.py +++ b/src/probnum/quad/solvers/policies/_max_aquisition_policy.py @@ -94,7 +94,6 @@ class MaxAcquisitionPolicy(Policy): The policy uses SciPy's 'Nelder-Mead' optimizer when gradients are unavailable. This is the current standard setting since ``probnum`` does not provide gradients yet. - """ def __init__( diff --git a/src/probnum/quad/solvers/stopping_criteria/_immediate_stop.py b/src/probnum/quad/solvers/stopping_criteria/_immediate_stop.py index 846f287ca..f469690ed 100644 --- a/src/probnum/quad/solvers/stopping_criteria/_immediate_stop.py +++ b/src/probnum/quad/solvers/stopping_criteria/_immediate_stop.py @@ -7,9 +7,10 @@ class ImmediateStop(BQStoppingCriterion): - """Dummy stopping criterion that always stops. This is useful for fixed datasets - when no policy or acquisition loop is required or given. + """Dummy stopping criterion that always stops. + This is useful for fixed datasets when no policy or acquisition loop is required or + given. """ def __call__(self, bq_state: BQState, info: BQIterInfo) -> bool: diff --git a/src/probnum/quad/solvers/stopping_criteria/_integral_variance_tol.py b/src/probnum/quad/solvers/stopping_criteria/_integral_variance_tol.py index dbcfbbf52..91368687b 100644 --- a/src/probnum/quad/solvers/stopping_criteria/_integral_variance_tol.py +++ b/src/probnum/quad/solvers/stopping_criteria/_integral_variance_tol.py @@ -1,4 +1,4 @@ -"""Stopping criterion based on the absolute value of the integral variance""" +"""Stopping criterion based on the absolute value of the integral variance.""" from __future__ import annotations diff --git a/src/probnum/randprocs/__init__.py b/src/probnum/randprocs/__init__.py index 71f2983d5..33bf312cc 100644 --- a/src/probnum/randprocs/__init__.py +++ b/src/probnum/randprocs/__init__.py @@ -1,9 +1,8 @@ """Random Processes. -Random processes generalize functions by encoding uncertainty over -function values in their covariance function. They can be used to model -(deterministic) functions which are not fully known or to define -functions with stochastic output. +Random processes generalize functions by encoding uncertainty over function values in +their covariance function. They can be used to model (deterministic) functions which are +not fully known or to define functions with stochastic output. """ from . import covfuncs, kernels, markov diff --git a/src/probnum/randprocs/covfuncs/__init__.py b/src/probnum/randprocs/covfuncs/__init__.py index ca5d8dbcd..c9fb9d4e9 100644 --- a/src/probnum/randprocs/covfuncs/__init__.py +++ b/src/probnum/randprocs/covfuncs/__init__.py @@ -1,11 +1,11 @@ """Covariance functions. -Covariance functions describe the spatial or temporal variation of a random process. -If evaluated at two sets of points, a covariance function computes the covariance of the +Covariance functions describe the spatial or temporal variation of a random process. If +evaluated at two sets of points, a covariance function computes the covariance of the values of the random process at these locations. -Covariance functions support basic algebraic operations, including scaling, addition -and multiplication. +Covariance functions support basic algebraic operations, including scaling, addition and +multiplication. """ from ._covariance_function import CovarianceFunction, IsotropicMixin diff --git a/src/probnum/randprocs/covfuncs/_arithmetic.py b/src/probnum/randprocs/covfuncs/_arithmetic.py index 01a06e6fb..bf178a9df 100644 --- a/src/probnum/randprocs/covfuncs/_arithmetic.py +++ b/src/probnum/randprocs/covfuncs/_arithmetic.py @@ -1,4 +1,5 @@ """Covariance function arithmetic.""" + from ._arithmetic_fallbacks import SumCovarianceFunction, _mul_fallback from ._covariance_function import BinaryOperandType, CovarianceFunction diff --git a/src/probnum/randprocs/covfuncs/_covariance_function.py b/src/probnum/randprocs/covfuncs/_covariance_function.py index 77898ec3b..3efb02b7d 100644 --- a/src/probnum/randprocs/covfuncs/_covariance_function.py +++ b/src/probnum/randprocs/covfuncs/_covariance_function.py @@ -169,8 +169,10 @@ def __init__( def input_shape_0(self) -> ShapeType: r""":attr:`~probnum.randprocs.RandomProcess.input_shape` of the :class:`~probnum.randprocs.RandomProcess` :math:`f_0`. + This defines the shape of a single, i.e. non-batched, first argument :math:`x_0` - of the :class:`CovarianceFunction`.""" + of the :class:`CovarianceFunction`. + """ return self._input_shape_0 @property @@ -187,8 +189,10 @@ def input_size_0(self) -> int: def input_shape_1(self) -> ShapeType: r""":attr:`~probnum.randprocs.RandomProcess.input_shape` of the :class:`~probnum.randprocs.RandomProcess` :math:`f_1`. + This defines the shape of a single, i.e. non-batched, second argument - :math:`x_1` of the :class:`CovarianceFunction`.""" + :math:`x_1` of the :class:`CovarianceFunction`. + """ return self._input_shape_1 @property @@ -417,9 +421,8 @@ def linop( x0: ArrayLike, x1: Optional[ArrayLike] = None, ) -> linops.LinearOperator: - r""":class:`~probnum.linops.LinearOperator` representing the pairwise - covariances of evaluations of :math:`f_0` and :math:`f_1` at the given input - points. + r""":class:`~probnum.linops.LinearOperator` representing the pairwise covariances + of evaluations of :math:`f_0` and :math:`f_1` at the given input points. Representing the resulting covariance matrix as a matrix-free :class:`~probnum.\ linops.LinearOperator` is often more efficient than a representation as a @@ -711,10 +714,8 @@ def _euclidean_inner_products( #################################################################################### __array_ufunc__ = None - """ - This prevents numpy from calling elementwise arithmetic operations instead of - the arithmetic operations defined by `CovarianceFunction`. - """ + """This prevents numpy from calling elementwise arithmetic operations instead of the + arithmetic operations defined by `CovarianceFunction`.""" def __add__(self, other: BinaryOperandType) -> CovarianceFunction: # pylint: disable=import-outside-toplevel,cyclic-import @@ -817,17 +818,26 @@ def _squared_euclidean_distances_keops( if x1 is None: x1 = x0 + + def convert_for_keops(arr): + """Convert array to KeOps-compatible format.""" + # Ensure contiguous memory layout and explicit dtype + arr = np.ascontiguousarray(arr, dtype=np.float64) + return arr + if len(x0.shape) < 2: x0 = x0.reshape(-1, 1) if len(x1.shape) < 2: x1 = x1.reshape(-1, 1) - sqdiffs = Vi(x0) - Vj(x1) + x0 = convert_for_keops(x0) + x1 = convert_for_keops(x1) - if scale_factors is not None: - sqdiffs *= Pm(scale_factors) + sqdiffs = (Vi(x0) - Vj(x1)) ** 2 - sqdiffs *= sqdiffs + if scale_factors is not None: + scale_factors = convert_for_keops(scale_factors) + sqdiffs = sqdiffs * Pm(scale_factors**2) return sqdiffs.sum() diff --git a/src/probnum/randprocs/covfuncs/_covariance_linear_operator.py b/src/probnum/randprocs/covfuncs/_covariance_linear_operator.py index 6d00de209..928d3939d 100644 --- a/src/probnum/randprocs/covfuncs/_covariance_linear_operator.py +++ b/src/probnum/randprocs/covfuncs/_covariance_linear_operator.py @@ -20,9 +20,8 @@ class CovarianceLinearOperator(linops.LinearOperator): - """:class:`~probnum.linops.LinearOperator` representing the pairwise - covariances of evaluations of :math:`f_0` and :math:`f_1` at the given input - points. + """:class:`~probnum.linops.LinearOperator` representing the pairwise covariances of + evaluations of :math:`f_0` and :math:`f_1` at the given input points. Supports both KeOps-based and standard implementations, but will prefer KeOps-based implementations by default. @@ -68,6 +67,7 @@ def __init__( def keops_lazy_tensor(self) -> Optional["LazyTensor"]: """:class:`~pykeops.numpy.LazyTensor` representing the covariance matrix corresponding to the given batches of input points. + When not using KeOps, this is set to :data:`None`. """ return self._keops_lazy_tensor diff --git a/src/probnum/randprocs/covfuncs/_matern.py b/src/probnum/randprocs/covfuncs/_matern.py index d48e97a47..ae49d5a7e 100644 --- a/src/probnum/randprocs/covfuncs/_matern.py +++ b/src/probnum/randprocs/covfuncs/_matern.py @@ -140,7 +140,8 @@ def p(self) -> Optional[int]: is not a half-integer, this is set to :data:`None`. Sample paths of a Gaussian process with this covariance function are - :math:`p`-times continuously differentiable.""" + :math:`p`-times continuously differentiable. + """ nu_minus_half = self._nu - 0.5 # Half-integer values can be represented exactly in IEEE 754 floating point diff --git a/src/probnum/randprocs/kernels.py b/src/probnum/randprocs/kernels.py index 8ac9d2ca3..4605d3bd5 100644 --- a/src/probnum/randprocs/kernels.py +++ b/src/probnum/randprocs/kernels.py @@ -5,6 +5,7 @@ The module is deprecated and should not be used in new code. Use :mod:`probnum.randprocs.covfuncs` instead. """ + from .covfuncs import * # pylint: disable=wildcard-import,unused-wildcard-import Kernel = CovarianceFunction diff --git a/src/probnum/randprocs/markov/_transition.py b/src/probnum/randprocs/markov/_transition.py index 25c94f004..3d5f2310e 100644 --- a/src/probnum/randprocs/markov/_transition.py +++ b/src/probnum/randprocs/markov/_transition.py @@ -61,8 +61,8 @@ def __repr__(self): def forward_rv( self, rv, t, dt=None, compute_gain=False, _diffusion=1.0, _linearise_at=None ): - r"""Forward-pass of a state, according to the transition. In other words, - return a description of + r"""Forward-pass of a state, according to the transition. In other words, return + a description of. .. math:: p(\mathcal{G}_t[x(t)] \,|\, x(t)), @@ -116,8 +116,8 @@ def forward_realization( _diffusion=1.0, _linearise_at=None, ): - r"""Forward-pass of a realization of a state, according to the transition. - In other words, return a description of + r"""Forward-pass of a realization of a state, according to the transition. In + other words, return a description of. .. math:: p(\mathcal{G}_t[x(t)] \,|\, x(t)=\xi), @@ -168,8 +168,8 @@ def backward_rv( _diffusion=1.0, _linearise_at=None, ): - r"""Backward-pass of a state, according to the transition. In other words, - return a description of + r"""Backward-pass of a state, according to the transition. In other words, return + a description of. .. math:: p(x(t) \,|\, z_{\mathcal{G}_t}) @@ -242,8 +242,8 @@ def backward_realization( _diffusion=1.0, _linearise_at=None, ): - r"""Backward-pass of a realisation of a state, according to the transition. - In other words, return a description of + r"""Backward-pass of a realisation of a state, according to the transition. In + other words, return a description of. .. math:: p(x(t) \,|\, {\mathcal{G}_t(x(t)) = \xi}) diff --git a/src/probnum/randprocs/markov/continuous/_diffusions.py b/src/probnum/randprocs/markov/continuous/_diffusions.py index 43d33cf1d..221c43118 100644 --- a/src/probnum/randprocs/markov/continuous/_diffusions.py +++ b/src/probnum/randprocs/markov/continuous/_diffusions.py @@ -1,6 +1,5 @@ """Diffusion models and their calibration.""" - import abc from typing import Union @@ -12,8 +11,8 @@ class Diffusion(abc.ABC): - r"""Interface for diffusion models - :math:`\sigma: \mathbb{R} \rightarrow \mathbb{R}^d` and their calibration.""" + r"""Interface for diffusion models :math:`\sigma: \mathbb{R} \rightarrow + \mathbb{R}^d` and their calibration.""" def __repr__(self): raise NotImplementedError diff --git a/src/probnum/randprocs/markov/continuous/_lti_sde.py b/src/probnum/randprocs/markov/continuous/_lti_sde.py index c90f3253b..990c38242 100644 --- a/src/probnum/randprocs/markov/continuous/_lti_sde.py +++ b/src/probnum/randprocs/markov/continuous/_lti_sde.py @@ -1,4 +1,5 @@ """LTI SDE models as transitions.""" + import functools import numpy as np diff --git a/src/probnum/randprocs/markov/continuous/_mfd.py b/src/probnum/randprocs/markov/continuous/_mfd.py index a9f4f317d..ae3142258 100644 --- a/src/probnum/randprocs/markov/continuous/_mfd.py +++ b/src/probnum/randprocs/markov/continuous/_mfd.py @@ -1,6 +1,5 @@ """Continuous-time transition utility functions.""" - import numpy as np import scipy.linalg diff --git a/src/probnum/randprocs/markov/discrete/_linear_gaussian.py b/src/probnum/randprocs/markov/discrete/_linear_gaussian.py index 150d095c7..30b04fce2 100644 --- a/src/probnum/randprocs/markov/discrete/_linear_gaussian.py +++ b/src/probnum/randprocs/markov/discrete/_linear_gaussian.py @@ -1,4 +1,5 @@ """Discrete, linear Gaussian transitions.""" + import typing from typing import Callable, Tuple import warnings diff --git a/src/probnum/randprocs/markov/discrete/_lti_gaussian.py b/src/probnum/randprocs/markov/discrete/_lti_gaussian.py index 1971b2769..5b59f2fc3 100644 --- a/src/probnum/randprocs/markov/discrete/_lti_gaussian.py +++ b/src/probnum/randprocs/markov/discrete/_lti_gaussian.py @@ -1,6 +1,5 @@ """Discrete, linear, time-invariant Gaussian transitions.""" - from probnum import randvars from probnum.randprocs.markov.discrete import _linear_gaussian from probnum.typing import ArrayLike, LinearOperatorLike diff --git a/src/probnum/randprocs/markov/integrator/_integrator.py b/src/probnum/randprocs/markov/integrator/_integrator.py index 22c23e9ec..ebc74fdc9 100644 --- a/src/probnum/randprocs/markov/integrator/_integrator.py +++ b/src/probnum/randprocs/markov/integrator/_integrator.py @@ -93,7 +93,6 @@ def _derivwise2coordwise_projmat(self) -> np.ndarray: -------- :attr:`Integrator._convert_coordwise_to_derivwise` :attr:`Integrator._convert_derivwise_to_coordwise` - """ dim = (self.num_derivatives + 1) * self.wiener_process_dimension projmat = np.zeros((dim, dim)) @@ -130,6 +129,5 @@ def _coordwise2derivwise_projmat(self) -> np.ndarray: -------- :attr:`Integrator._convert_coordwise_to_derivwise` :attr:`Integrator._convert_derivwise_to_coordwise` - """ return self._derivwise2coordwise_projmat.T diff --git a/src/probnum/randprocs/markov/integrator/_ioup.py b/src/probnum/randprocs/markov/integrator/_ioup.py index e024c35b0..aa78e963c 100644 --- a/src/probnum/randprocs/markov/integrator/_ioup.py +++ b/src/probnum/randprocs/markov/integrator/_ioup.py @@ -1,4 +1,5 @@ """Integrated Ornstein-Uhlenbeck processes.""" + import warnings import numpy as np @@ -73,6 +74,7 @@ class IntegratedOrnsteinUhlenbeckProcess(_markov.MarkovProcess): >>> print(ioup4) """ # pylint: disable=line-too-long + # Doctest/Example blocks in the docstring above cannot be made to comply with line # length rule because adding newlines in them will cause rendered page to have # unwanted newlines. diff --git a/src/probnum/randprocs/markov/integrator/_iwp.py b/src/probnum/randprocs/markov/integrator/_iwp.py index b62c6ac59..e0aa8dd25 100644 --- a/src/probnum/randprocs/markov/integrator/_iwp.py +++ b/src/probnum/randprocs/markov/integrator/_iwp.py @@ -74,6 +74,7 @@ class IntegratedWienerProcess(_markov.MarkovProcess): >>> print(iwp4) """ # pylint: disable=line-too-long + # Doctest/Example blocks in the docstring above cannot be made to comply with line # length rule because adding newlines in them will cause rendered page to have # unwanted newlines. diff --git a/src/probnum/randprocs/markov/integrator/_matern.py b/src/probnum/randprocs/markov/integrator/_matern.py index e8db12d82..17511d9ff 100644 --- a/src/probnum/randprocs/markov/integrator/_matern.py +++ b/src/probnum/randprocs/markov/integrator/_matern.py @@ -1,4 +1,5 @@ """Matern processes.""" + import warnings import numpy as np @@ -73,6 +74,7 @@ class MaternProcess(_markov.MarkovProcess): >>> print(matern4) """ # pylint: disable=line-too-long + # Doctest/Example blocks in the docstring above cannot be made to comply with line # length rule because adding newlines in them will cause rendered page to have # unwanted newlines. diff --git a/src/probnum/randvars/_categorical.py b/src/probnum/randvars/_categorical.py index a66955635..ba79ef6c9 100644 --- a/src/probnum/randvars/_categorical.py +++ b/src/probnum/randvars/_categorical.py @@ -1,4 +1,5 @@ """Categorical random variables.""" + from typing import Optional import numpy as np diff --git a/src/probnum/randvars/_constant.py b/src/probnum/randvars/_constant.py index 5deee4d6d..b02b416e4 100644 --- a/src/probnum/randvars/_constant.py +++ b/src/probnum/randvars/_constant.py @@ -170,7 +170,7 @@ def __abs__(self) -> "Constant": @staticmethod def _binary_operator_factory( - operator: Callable[[ValueType, ValueType], ValueType] + operator: Callable[[ValueType, ValueType], ValueType], ) -> Callable[["Constant", "Constant"], "Constant"]: def _constant_rv_binary_operator( constant_rv1: Constant, constant_rv2: Constant diff --git a/src/probnum/randvars/_normal.py b/src/probnum/randvars/_normal.py index 4f0ef12c7..7ff193a1a 100644 --- a/src/probnum/randvars/_normal.py +++ b/src/probnum/randvars/_normal.py @@ -1,4 +1,5 @@ """Normally distributed / Gaussian random variables.""" + from __future__ import annotations from functools import cached_property @@ -238,8 +239,8 @@ def __init__( @property def cov_cholesky(self) -> ValueType: - """Cholesky factor :math:`L` of the covariance - :math:`\\operatorname{Cov}(X) =LL^\\top`.""" + """Cholesky factor :math:`L` of the covariance :math:`\\operatorname{Cov}(X) + =LL^\\top`.""" if not self.cov_cholesky_is_precomputed: self.precompute_cov_cholesky() diff --git a/src/probnum/randvars/_random_variable.py b/src/probnum/randvars/_random_variable.py index e87e05e6d..d9fe20981 100644 --- a/src/probnum/randvars/_random_variable.py +++ b/src/probnum/randvars/_random_variable.py @@ -1,4 +1,5 @@ """Random Variables.""" + from __future__ import annotations from functools import cached_property @@ -198,7 +199,9 @@ def median_dtype(self) -> np.dtype: @property def moment_dtype(self) -> np.dtype: """The dtype of any (function of a) moment of the random variable, e.g. its - :attr:`mean`, :attr:`cov`, :attr:`var`, or :attr:`std`. It will be set to the + :attr:`mean`, :attr:`cov`, :attr:`var`, or :attr:`std`. + + It will be set to the dtype arising from the multiplication of values with dtypes :attr:`dtype` and :class:`numpy.float_`. This is motivated by the mathematical definition of a moment as a sum or an integral over products of probabilities and values of the @@ -291,7 +294,8 @@ def mean(self) -> ValueType: @cached_property def cov(self) -> ValueType: - """Covariance :math:`\\operatorname{Cov}(X) = \\mathbb{E}((X-\\mathbb{E}(X))(X-\\mathbb{E}(X))^\\top)` of the random variable. + """Covariance :math:`\\operatorname{Cov}(X) = + \\mathbb{E}((X-\\mathbb{E}(X))(X-\\mathbb{E}(X))^\\top)` of the random variable. To learn about the dtype of the covariance, see :attr:`moment_dtype`. """ # pylint: disable=line-too-long @@ -951,7 +955,7 @@ class DiscreteRandomVariable(RandomVariable[ValueType]): array([1, 0, 1]) >>> x.pmf(2) array(0.) - >>> x.mean + >>> x.mean.item() 0.0 """ @@ -1165,7 +1169,7 @@ class ContinuousRandomVariable(RandomVariable[ValueType]): array([0.77395605, 0.43887844, 0.85859792]) >>> u.pdf(0.5) array(1.) - >>> u.var + >>> u.var.item() 0.08333333333333333 """ diff --git a/src/probnum/randvars/_scipy_stats.py b/src/probnum/randvars/_scipy_stats.py index 36b8470b0..7a55e4d61 100644 --- a/src/probnum/randvars/_scipy_stats.py +++ b/src/probnum/randvars/_scipy_stats.py @@ -128,7 +128,7 @@ def wrap_scipy_rv( scipy_rv: Union[ scipy.stats._distn_infrastructure.rv_frozen, scipy.stats._multivariate.multi_rv_frozen, - ] + ], ) -> _random_variable.RandomVariable: """Transform SciPy distributions to ProbNum :class:`RandomVariable`s. diff --git a/src/probnum/randvars/_utils.py b/src/probnum/randvars/_utils.py index ff9821cc6..7816a4a82 100644 --- a/src/probnum/randvars/_utils.py +++ b/src/probnum/randvars/_utils.py @@ -1,4 +1,5 @@ """Utility functions for random variables.""" + from typing import Any import numpy as np diff --git a/src/probnum/typing.py b/src/probnum/typing.py index 0c4bab250..eec115876 100644 --- a/src/probnum/typing.py +++ b/src/probnum/typing.py @@ -58,8 +58,8 @@ """Type defining a scalar.""" MatrixType = Union[np.ndarray, "probnum.linops.LinearOperator"] -"""Type defining a matrix, i.e. a linear map between \ -finite-dimensional vector spaces.""" +"""Type defining a matrix, i.e. a linear map between \ finite-dimensional vector +spaces.""" ######################################################################################## # Argument Types @@ -70,13 +70,15 @@ """Object that can be converted to an integer. Arguments of type :attr:`IntLike` should always be converted -into :class:`int`\\ s before further internal processing.""" +into :class:`int`\\ s before further internal processing. +""" FloatLike = Union[float, numbers.Real, np.floating] """Object that can be converted to a float. Arguments of type :attr:`FloatLike` should always be converted -into :class:`float`\\ s before further internal processing.""" +into :class:`float`\\ s before further internal processing. +""" # Array Utilities ShapeLike = Union[IntLike, Iterable[IntLike]] @@ -84,13 +86,15 @@ Arguments of type :attr:`ShapeLike` should always be converted into :class:`ShapeType` using the function :func:`probnum.utils.as_shape` -before further internal processing.""" +before further internal processing. +""" DTypeLike = _NumPyDTypeLike """Object that can be converted to an array dtype. Arguments of type :attr:`DTypeLike` should always be converted -into :class:`numpy.dtype`\\ s before further internal processing.""" +into :class:`numpy.dtype`\\ s before further internal processing. +""" _ArrayIndexLike = Union[ int, @@ -105,7 +109,8 @@ Type of the argument to the :meth:`__getitem__` method of a NumPy-like array type such as :class:`numpy.ndarray`, :class:`probnum.linops.LinearOperator` or -:class:`probnum.randvars.RandomVariable`.""" +:class:`probnum.randvars.RandomVariable`. +""" # Scalars, Arrays and Matrices ScalarLike = Union[int, float, complex, numbers.Number, np.number] @@ -113,14 +118,16 @@ Arguments of type :attr:`ScalarLike` should always be converted into :class:`numpy.number`\\ s using the function :func:`probnum.utils.as_scalar` -before further internal processing.""" +before further internal processing. +""" ArrayLike = _NumPyArrayLike """Object that can be converted to an array. Arguments of type :attr:`ArrayLike` should always be converted into :class:`numpy.ndarray`\\ s using the function :func:`np.asarray` -before further internal processing.""" +before further internal processing. +""" LinearOperatorLike = Union[ ArrayLike, @@ -132,7 +139,8 @@ Arguments of type :attr:`LinearOperatorLike` should always be converted into :class:`~probnum.linops.\\ LinearOperator`\\ s using the function :func:`probnum.linops.aslinop` before further -internal processing.""" +internal processing. +""" ######################################################################################## # Other Types diff --git a/src/probnum/utils/linalg/_cholesky_updates.py b/src/probnum/utils/linalg/_cholesky_updates.py index cdca28c12..d01dc987a 100644 --- a/src/probnum/utils/linalg/_cholesky_updates.py +++ b/src/probnum/utils/linalg/_cholesky_updates.py @@ -1,6 +1,5 @@ """Cholesky updates.""" - import typing import numpy as np @@ -11,8 +10,8 @@ def cholesky_update( S1: np.ndarray, S2: typing.Optional[np.ndarray] = None ) -> np.ndarray: - r"""Compute Cholesky update/factorization :math:`L` such that - :math:`L L^\top = S_1 S_1^\top + S_2 S_2^\top` holds. + r"""Compute Cholesky update/factorization :math:`L` such that :math:`L L^\top = S_1 + S_1^\top + S_2 S_2^\top` holds. This can be used in various ways. For example, :math:`S_1` and :math:`S_2` do not need to be Cholesky factors; any diff --git a/src/probnum/utils/linalg/_inner_product.py b/src/probnum/utils/linalg/_inner_product.py index d58441b4a..bc7f8ce3f 100644 --- a/src/probnum/utils/linalg/_inner_product.py +++ b/src/probnum/utils/linalg/_inner_product.py @@ -1,4 +1,5 @@ """Functions defining useful inner products.""" + from __future__ import annotations from typing import TYPE_CHECKING, Optional, Union diff --git a/tests/conftest.py b/tests/conftest.py index 4c8ef4478..53d6b8400 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- """Dummy conftest.py for probnum. -If you don't know what this is for, just leave it empty. Read more about -conftest.py under: https://pytest.org/latest/plugins.html +If you don't know what this is for, just leave it empty. Read more about conftest.py +under: +https://pytest.org/latest/plugins.html """ # import pytest diff --git a/tests/test_diffeq/test_callbacks/test_discrete_callback.py b/tests/test_diffeq/test_callbacks/test_discrete_callback.py index a4f984956..ce54e60a7 100644 --- a/tests/test_diffeq/test_callbacks/test_discrete_callback.py +++ b/tests/test_diffeq/test_callbacks/test_discrete_callback.py @@ -1,6 +1,5 @@ """Tests for discrete event handlers.""" - import dataclasses import pytest diff --git a/tests/test_diffeq/test_odefilter/test_init_routines/test_init_routines.py b/tests/test_diffeq/test_odefilter/test_init_routines/test_init_routines.py index a6d81d834..4d949ab19 100644 --- a/tests/test_diffeq/test_odefilter/test_init_routines/test_init_routines.py +++ b/tests/test_diffeq/test_odefilter/test_init_routines/test_init_routines.py @@ -1,6 +1,5 @@ """Tests for initialization routines.""" - import numpy as np import pytest import pytest_cases diff --git a/tests/test_diffeq/test_odefilter/test_odefilter.py b/tests/test_diffeq/test_odefilter/test_odefilter.py index 6d99e2ddd..5f619bfb3 100644 --- a/tests/test_diffeq/test_odefilter/test_odefilter.py +++ b/tests/test_diffeq/test_odefilter/test_odefilter.py @@ -1,6 +1,5 @@ """Tests for ODE filters.""" - import pytest import pytest_cases diff --git a/tests/test_diffeq/test_odefilter/test_odefilter_cases.py b/tests/test_diffeq/test_odefilter/test_odefilter_cases.py index f73d3014c..594244a59 100644 --- a/tests/test_diffeq/test_odefilter/test_odefilter_cases.py +++ b/tests/test_diffeq/test_odefilter/test_odefilter_cases.py @@ -1,6 +1,5 @@ """Test-cases for ODE filters.""" - import pytest_cases from probnum import diffeq, randprocs diff --git a/tests/test_diffeq/test_odefilter/test_odefilter_special.py b/tests/test_diffeq/test_odefilter/test_odefilter_special.py index e2c3a728e..a87961a55 100644 --- a/tests/test_diffeq/test_odefilter/test_odefilter_special.py +++ b/tests/test_diffeq/test_odefilter/test_odefilter_special.py @@ -3,6 +3,7 @@ The tests in here go through probsolve_ivp(), but do not directly test the interface, but the implementation. Therefore this test module is named w.r.t. ivpfiltsmooth.py. """ + import numpy as np import pytest diff --git a/tests/test_diffeq/test_odefilter/test_utils/test_problem_utils.py b/tests/test_diffeq/test_odefilter/test_utils/test_problem_utils.py index 317f1e22c..6142f9d92 100644 --- a/tests/test_diffeq/test_odefilter/test_utils/test_problem_utils.py +++ b/tests/test_diffeq/test_odefilter/test_utils/test_problem_utils.py @@ -1,6 +1,5 @@ """Test for utility functions for odefilter problem conversion.""" - import numpy as np import pytest diff --git a/tests/test_filtsmooth/conftest.py b/tests/test_filtsmooth/conftest.py index 0a8b18231..fe3e596dd 100644 --- a/tests/test_filtsmooth/conftest.py +++ b/tests/test_filtsmooth/conftest.py @@ -1,6 +1,5 @@ """Test fixtures for filtering and smoothing.""" - import numpy as np import pytest diff --git a/tests/test_filtsmooth/test_optim/test_stoppingcriterion.py b/tests/test_filtsmooth/test_optim/test_stoppingcriterion.py index a86cd454b..ce83ccd9e 100644 --- a/tests/test_filtsmooth/test_optim/test_stoppingcriterion.py +++ b/tests/test_filtsmooth/test_optim/test_stoppingcriterion.py @@ -1,6 +1,5 @@ """Test Kalman utility functions.""" - import numpy as np import pytest diff --git a/tests/test_linalg/test_solvers/cases/belief_updates.py b/tests/test_linalg/test_solvers/cases/belief_updates.py index 7629ad742..7cef43748 100644 --- a/tests/test_linalg/test_solvers/cases/belief_updates.py +++ b/tests/test_linalg/test_solvers/cases/belief_updates.py @@ -1,5 +1,6 @@ """Test cases describing different belief updates over quantities of interest of a linear system.""" + from pytest_cases import parametrize from probnum.linalg.solvers.belief_updates import matrix_based, solution_based diff --git a/tests/test_linalg/test_solvers/cases/policies.py b/tests/test_linalg/test_solvers/cases/policies.py index 9a942ea62..aae104e33 100644 --- a/tests/test_linalg/test_solvers/cases/policies.py +++ b/tests/test_linalg/test_solvers/cases/policies.py @@ -1,4 +1,5 @@ """Test cases defined by policies.""" + from pytest_cases import case from probnum.linalg.solvers import policies diff --git a/tests/test_linalg/test_solvers/conftest.py b/tests/test_linalg/test_solvers/conftest.py index 80cf5e88d..5fe3553ae 100644 --- a/tests/test_linalg/test_solvers/conftest.py +++ b/tests/test_linalg/test_solvers/conftest.py @@ -1,4 +1,5 @@ """Test fixtures for linear solvers.""" + from pytest_cases import fixture, parametrize diff --git a/tests/test_linalg/test_solvers/test_beliefs/test_linear_system_belief.py b/tests/test_linalg/test_solvers/test_beliefs/test_linear_system_belief.py index 25ad93b3f..cae9e50d0 100644 --- a/tests/test_linalg/test_solvers/test_beliefs/test_linear_system_belief.py +++ b/tests/test_linalg/test_solvers/test_beliefs/test_linear_system_belief.py @@ -1,4 +1,5 @@ """Tests for beliefs about quantities of interest of a linear system.""" + import numpy as np import pytest diff --git a/tests/test_linalg/test_solvers/test_policies/test_conjugate_gradient.py b/tests/test_linalg/test_solvers/test_policies/test_conjugate_gradient.py index 60f5d142b..2a2e240f9 100644 --- a/tests/test_linalg/test_solvers/test_policies/test_conjugate_gradient.py +++ b/tests/test_linalg/test_solvers/test_policies/test_conjugate_gradient.py @@ -1,4 +1,5 @@ """Tests for a policy returning random unit vectors.""" + import copy import pathlib diff --git a/tests/test_linalg/test_solvers/test_policies/test_linear_solver_policy.py b/tests/test_linalg/test_solvers/test_policies/test_linear_solver_policy.py index 0d51acae2..dc9d58b2b 100644 --- a/tests/test_linalg/test_solvers/test_policies/test_linear_solver_policy.py +++ b/tests/test_linalg/test_solvers/test_policies/test_linear_solver_policy.py @@ -1,4 +1,5 @@ """Tests for probabilistic linear solver policies.""" + import copy import pathlib diff --git a/tests/test_linalg/test_solvers/test_policies/test_random_unit_vector.py b/tests/test_linalg/test_solvers/test_policies/test_random_unit_vector.py index 8201c2705..331b6080a 100644 --- a/tests/test_linalg/test_solvers/test_policies/test_random_unit_vector.py +++ b/tests/test_linalg/test_solvers/test_policies/test_random_unit_vector.py @@ -1,4 +1,5 @@ """Tests for a policy returning random unit vectors.""" + import pathlib import numpy as np diff --git a/tests/test_linalg/test_solvers/test_probabilistic_linear_solver/test_symmetric.py b/tests/test_linalg/test_solvers/test_probabilistic_linear_solver/test_symmetric.py index 734342e7d..09c85c9b8 100644 --- a/tests/test_linalg/test_solvers/test_probabilistic_linear_solver/test_symmetric.py +++ b/tests/test_linalg/test_solvers/test_probabilistic_linear_solver/test_symmetric.py @@ -1,4 +1,5 @@ """Tests for probabilistic linear solvers applied to symmetric linear systems.""" + import pathlib import numpy as np diff --git a/tests/test_linops/test_arithmetics.py b/tests/test_linops/test_arithmetics.py index 8b3b1313d..aa232fbb8 100644 --- a/tests/test_linops/test_arithmetics.py +++ b/tests/test_linops/test_arithmetics.py @@ -1,4 +1,5 @@ """Tests for linear operator arithmetics.""" + # pylint: disable=consider-iterating-dictionary import itertools @@ -34,7 +35,10 @@ def _aslist(arg): - """Converts anything to a list. Non-iterables become single-element lists.""" + """Converts anything to a list. + + Non-iterables become single-element lists. + """ try: return list(arg) except TypeError: # excepts TypeError: '' object is not iterable @@ -105,7 +109,7 @@ def get_linop(linop_type): def test_matmul(): - for (l_type, r_type) in _matmul_fns.keys(): + for l_type, r_type in _matmul_fns.keys(): if ( l_type is Selection or l_type is Embedding @@ -118,7 +122,7 @@ def test_matmul(): linops1 = get_linop(l_type) linops2 = get_linop(r_type) - for (linop1, linop2) in itertools.product(_aslist(linops1), _aslist(linops2)): + for linop1, linop2 in itertools.product(_aslist(linops1), _aslist(linops2)): if linop1.shape[1] != linop2.shape[0]: with pytest.raises(ValueError): @@ -137,7 +141,7 @@ def test_matmul(): def test_mul(): - for (l_type, r_type) in _mul_fns.keys(): + for l_type, r_type in _mul_fns.keys(): if ( l_type is Selection or l_type is Embedding @@ -150,7 +154,7 @@ def test_mul(): linops1 = get_linop(l_type) linops2 = get_linop(r_type) - for (linop1, linop2) in itertools.product(_aslist(linops1), _aslist(linops2)): + for linop1, linop2 in itertools.product(_aslist(linops1), _aslist(linops2)): if l_type is np.number: res_linop = linop1 * linop2 @@ -168,7 +172,7 @@ def test_mul(): def test_add(): - for (l_type, r_type) in _add_fns.keys(): + for l_type, r_type in _add_fns.keys(): if ( l_type is Selection or l_type is Embedding @@ -181,7 +185,7 @@ def test_add(): linops1 = get_linop(l_type) linops2 = get_linop(r_type) - for (linop1, linop2) in itertools.product(_aslist(linops1), _aslist(linops2)): + for linop1, linop2 in itertools.product(_aslist(linops1), _aslist(linops2)): if linop1.shape != linop2.shape: with pytest.raises(ValueError): @@ -193,7 +197,7 @@ def test_add(): def test_sub(): - for (l_type, r_type) in _sub_fns.keys(): + for l_type, r_type in _sub_fns.keys(): if ( l_type is Selection or l_type is Embedding @@ -206,7 +210,7 @@ def test_sub(): linops1 = get_linop(l_type) linops2 = get_linop(r_type) - for (linop1, linop2) in itertools.product(_aslist(linops1), _aslist(linops2)): + for linop1, linop2 in itertools.product(_aslist(linops1), _aslist(linops2)): if linop1.shape != linop2.shape: with pytest.raises(ValueError): diff --git a/tests/test_linops/test_linop_decompositions.py b/tests/test_linops/test_linop_decompositions.py index 19b3644fd..0849e20fb 100644 --- a/tests/test_linops/test_linop_decompositions.py +++ b/tests/test_linops/test_linop_decompositions.py @@ -70,8 +70,8 @@ def test_cholesky(linop: pn.linops.LinearOperator, matrix: np.ndarray, lower: bo def test_cholesky_is_symmetric_not_true( linop: pn.linops.LinearOperator, matrix: np.ndarray, lower: bool ): # pylint: disable=unused-argument - """Tests whether computing the Cholesky decomposition of a ``LinearOperator`` - whose ``is_symmetric`` property is not set to ``True`` results in an error.""" + """Tests whether computing the Cholesky decomposition of a ``LinearOperator`` whose + ``is_symmetric`` property is not set to ``True`` results in an error.""" if linop.is_symmetric is not True: with pytest.raises(np.linalg.LinAlgError): @@ -86,8 +86,8 @@ def test_cholesky_is_symmetric_not_true( def test_cholesky_is_positive_definite_false( linop: pn.linops.LinearOperator, matrix: np.ndarray, lower: bool ): # pylint: disable=unused-argument - """Tests whether computing the Cholesky decomposition of a ``LinearOperator`` - whose ``is_symmetric`` property is not set to ``True`` results in an error.""" + """Tests whether computing the Cholesky decomposition of a ``LinearOperator`` whose + ``is_symmetric`` property is not set to ``True`` results in an error.""" if linop.is_positive_definite is False: with pytest.raises(np.linalg.LinAlgError): @@ -111,7 +111,7 @@ def test_cholesky_not_positive_definite( linop: pn.linops.LinearOperator, matrix: np.ndarray, lower: bool ): """Tests whether computing the Cholesky decomposition of a symmetric, but not - positive definite matrix results in an error""" + positive definite matrix results in an error.""" expected_exception = None diff --git a/tests/test_problems/test_zoo/test_diffeq/test_ivp_examples_jax.py b/tests/test_problems/test_zoo/test_diffeq/test_ivp_examples_jax.py index 6c932e28e..64f4d4895 100644 --- a/tests/test_problems/test_zoo/test_diffeq/test_ivp_examples_jax.py +++ b/tests/test_problems/test_zoo/test_diffeq/test_ivp_examples_jax.py @@ -6,7 +6,7 @@ # pylint: disable=unused-import try: import jax - from jax.config import config + from jax import config import jax.numpy as jnp config.update("jax_enable_x64", True) @@ -50,6 +50,7 @@ def test_ddf(ivp_jax): # Tests for when JAX is not available +# These tests are now skipped when JAX is available since it's installed in tox @only_if_jax_is_not_available @@ -62,3 +63,24 @@ def test_threebody(): def test_vanderpol(): with pytest.raises(ImportError): diffeq_zoo.vanderpol_jax() + + +# Additional tests for when JAX is available +@only_if_jax_available +def test_threebody_available(): + """Test that threebody_jax works when JAX is available.""" + ivp = diffeq_zoo.threebody_jax() + assert ivp is not None + assert hasattr(ivp, "f") + assert hasattr(ivp, "df") + assert hasattr(ivp, "ddf") + + +@only_if_jax_available +def test_vanderpol_available(): + """Test that vanderpol_jax works when JAX is available.""" + ivp = diffeq_zoo.vanderpol_jax() + assert ivp is not None + assert hasattr(ivp, "f") + assert hasattr(ivp, "df") + assert hasattr(ivp, "ddf") diff --git a/tests/test_problems/test_zoo/test_quad/test_problems.py b/tests/test_problems/test_zoo/test_quad/test_problems.py index 59fee2edc..5ca51ac3e 100644 --- a/tests/test_problems/test_zoo/test_quad/test_problems.py +++ b/tests/test_problems/test_zoo/test_quad/test_problems.py @@ -9,7 +9,7 @@ @pytest.fixture(params=[hennig1d, hennig2d, sombrero2d, circulargaussian2d]) def problem(request): - """quad problems with default values""" + """Quad problems with default values.""" return request.param() @@ -22,7 +22,7 @@ def problem(request): ids=["hennig2d", "circulargaussian2d", "sombrero2d"], ) def problem_parametrized(request): - """quad problems with custom parameters""" + """Quad problems with custom parameters.""" return request.param[0](**request.param[1]) diff --git a/tests/test_problems/test_zoo/test_quad/test_quadproblems_uniform.py b/tests/test_problems/test_zoo/test_quad/test_quadproblems_uniform.py index 2d514e0bb..14495c452 100644 --- a/tests/test_problems/test_zoo/test_quad/test_quadproblems_uniform.py +++ b/tests/test_problems/test_zoo/test_quad/test_quadproblems_uniform.py @@ -67,7 +67,7 @@ def test_genz_uniform_param_checks(genz_problem): ], ) def test_integrand_eval_checks( - quad_problem_constructor: Callable[..., QuadratureProblem] + quad_problem_constructor: Callable[..., QuadratureProblem], ): quad_problem = quad_problem_constructor(2) diff --git a/tests/test_quad/test_bayesian_quadrature.py b/tests/test_quad/test_bayesian_quadrature.py index 4e795b461..4d721c052 100644 --- a/tests/test_quad/test_bayesian_quadrature.py +++ b/tests/test_quad/test_bayesian_quadrature.py @@ -174,8 +174,8 @@ def test_bq_from_problem_options_values_default(): def test_bq_from_problem_options_values_custom(): - """Test if custom values of the options dictionary are set correctly - (apart from design and policy options).""" + """Test if custom values of the options dictionary are set correctly (apart from + design and policy options).""" # batch_size manual value batch_size = 3 diff --git a/tests/test_quad/test_bayesquad/test_bq.py b/tests/test_quad/test_bayesquad/test_bq.py index 5365e68da..23fa28ba8 100644 --- a/tests/test_quad/test_bayesquad/test_bq.py +++ b/tests/test_quad/test_bayesquad/test_bq.py @@ -1,4 +1,5 @@ """Test cases for Bayesian quadrature.""" + import copy import numpy as np @@ -197,8 +198,8 @@ def test_domain_ignored_if_lebesgue(input_dim, measure, rng): def test_zero_function_gives_zero_variance_with_mle(rng): - """Test that BQ variance is zero for zero function when MLE is used to set the - scale parameter.""" + """Test that BQ variance is zero for zero function when MLE is used to set the scale + parameter.""" input_dim = 1 domain = (0, 1) fun = lambda x: np.zeros(x.shape[0]) diff --git a/tests/test_quad/test_initial_designs.py b/tests/test_quad/test_initial_designs.py index df6a6bb0d..1a3e018a5 100644 --- a/tests/test_quad/test_initial_designs.py +++ b/tests/test_quad/test_initial_designs.py @@ -1,6 +1,5 @@ """Test cases for initial designs.""" - # New designs need to be added to the fixture 'design'. diff --git a/tests/test_quad/util.py b/tests/test_quad/util.py index 84397c055..6663b2976 100644 --- a/tests/test_quad/util.py +++ b/tests/test_quad/util.py @@ -1,4 +1,5 @@ """Auxiliary functions used in tests for quadrature methods.""" + from typing import Optional, Tuple, Union import numpy as np diff --git a/tests/test_randprocs/test_covfuncs/test_arithmetic.py b/tests/test_randprocs/test_covfuncs/test_arithmetic.py index 13f6a2c93..d4efd99da 100644 --- a/tests/test_randprocs/test_covfuncs/test_arithmetic.py +++ b/tests/test_randprocs/test_covfuncs/test_arithmetic.py @@ -1,4 +1,5 @@ """Tests for covariance function arithmetic.""" + from probnum.randprocs import covfuncs from probnum.randprocs.covfuncs._arithmetic_fallbacks import ( ProductCovarianceFunction, diff --git a/tests/test_randprocs/test_covfuncs/test_call.py b/tests/test_randprocs/test_covfuncs/test_call.py index d430b6335..d8ba6a95a 100644 --- a/tests/test_randprocs/test_covfuncs/test_call.py +++ b/tests/test_randprocs/test_covfuncs/test_call.py @@ -41,8 +41,11 @@ def fixture_input_shapes( request, input_shape: ShapeType ) -> Tuple[ShapeType, Optional[ShapeType]]: - """Shapes for the first and second argument of the covariance function. The second - shape is ``None`` if the second argument to the covariance function is ``None``.""" + """Shapes for the first and second argument of the covariance function. + + The second + shape is ``None`` if the second argument to the covariance function is ``None``. + """ x0_shape, x1_shape = request.param diff --git a/tests/test_randprocs/test_markov/test_continuous/test_diffusions.py b/tests/test_randprocs/test_markov/test_continuous/test_diffusions.py index a5096a86f..ed105b662 100644 --- a/tests/test_randprocs/test_markov/test_continuous/test_diffusions.py +++ b/tests/test_randprocs/test_markov/test_continuous/test_diffusions.py @@ -12,8 +12,7 @@ def some_meas_rv1(): """Generic measurement RV used to test calibration. - This config should return 9.776307498421126 for - Diffusion.calibrate_locally. + This config should return 9.776307498421126 for Diffusion.calibrate_locally. """ some_mean = np.arange(10, 13) some_cov = np.arange(9).reshape((3, 3)) @ np.arange(9).reshape((3, 3)).T + np.eye(3) @@ -25,8 +24,7 @@ def some_meas_rv1(): def some_meas_rv2(): """Another generic measurement RV used to test calibration. - This config should return 9.776307498421126 for - Diffusion.calibrate_locally. + This config should return 9.776307498421126 for Diffusion.calibrate_locally. """ some_mean = np.arange(10, 13) some_cov = np.arange(3, 12).reshape((3, 3)) @ np.arange(3, 12).reshape( diff --git a/tests/test_randprocs/test_markov/test_continuous/test_linear_sde.py b/tests/test_randprocs/test_markov/test_continuous/test_linear_sde.py index 5e4970e81..e7c236688 100644 --- a/tests/test_randprocs/test_markov/test_continuous/test_linear_sde.py +++ b/tests/test_randprocs/test_markov/test_continuous/test_linear_sde.py @@ -65,14 +65,14 @@ def test_backward_realization(self, some_normal_rv1, some_normal_rv2): assert isinstance(out, randvars.Normal) def test_forward_realization_value_error_caught(self, some_normal_rv1): - """the forward realization only works if a time-increment dt is provided.""" + """The forward realization only works if a time-increment dt is provided.""" with pytest.raises(ValueError): self.transition.forward_realization(some_normal_rv1.mean, t=0.0) def test_backward_realization_value_error_caught( self, some_normal_rv1, some_normal_rv2 ): - """the backward realization only works if a time-increment dt is provided.""" + """The backward realization only works if a time-increment dt is provided.""" with pytest.raises(ValueError): out, _ = self.transition.backward_realization( some_normal_rv1.mean, @@ -155,7 +155,7 @@ def test_solve_mde_forward_sqrt_values( v_const, diffusion, ): - """mde forward values in sqrt-implementation and classic implementation should be + """Mde forward values in sqrt-implementation and classic implementation should be equal.""" out_linear, _ = ltisde_as_linearsde.forward_realization( v_const, t=0.0, dt=0.1, _diffusion=diffusion diff --git a/tests/test_randprocs/test_markov/test_integrator/test_ioup.py b/tests/test_randprocs/test_markov/test_integrator/test_ioup.py index ab59d5fb4..f486a56db 100644 --- a/tests/test_randprocs/test_markov/test_integrator/test_ioup.py +++ b/tests/test_randprocs/test_markov/test_integrator/test_ioup.py @@ -1,6 +1,5 @@ """Tests for IntegratedOrnsteinUhlenbeckProcessTransitions.""" - import numpy as np import pytest diff --git a/tests/test_randprocs/test_markov/test_integrator/test_matern.py b/tests/test_randprocs/test_markov/test_integrator/test_matern.py index 97ce8a8e6..ffae9d9e7 100644 --- a/tests/test_randprocs/test_markov/test_integrator/test_matern.py +++ b/tests/test_randprocs/test_markov/test_integrator/test_matern.py @@ -1,6 +1,5 @@ """Tests for Matern processes.""" - import numpy as np import pytest diff --git a/tests/test_randvars/test_arithmetic/conftest.py b/tests/test_randvars/test_arithmetic/conftest.py index 7522c99ae..7ff741f8a 100644 --- a/tests/test_randvars/test_arithmetic/conftest.py +++ b/tests/test_randvars/test_arithmetic/conftest.py @@ -1,4 +1,5 @@ """Fixtures for random variable arithmetic.""" + import numpy as np import pytest diff --git a/tests/test_randvars/test_arithmetic/test_constant.py b/tests/test_randvars/test_arithmetic/test_constant.py index d0abbe45f..96f260ac0 100644 --- a/tests/test_randvars/test_arithmetic/test_constant.py +++ b/tests/test_randvars/test_arithmetic/test_constant.py @@ -1,4 +1,5 @@ """Tests for random variable arithmetic for constants.""" + import operator from typing import Callable diff --git a/tests/test_randvars/test_categorical.py b/tests/test_randvars/test_categorical.py index f4bd9b961..30aef9244 100644 --- a/tests/test_randvars/test_categorical.py +++ b/tests/test_randvars/test_categorical.py @@ -1,6 +1,5 @@ """Tests for the categorical random variable.""" - import string import numpy as np diff --git a/tests/test_randvars/test_constant.py b/tests/test_randvars/test_constant.py index cb46dcdb9..7830de2bf 100644 --- a/tests/test_randvars/test_constant.py +++ b/tests/test_randvars/test_constant.py @@ -1,4 +1,5 @@ """Tests for constant random variables.""" + import unittest import numpy as np diff --git a/tests/test_randvars/test_normal.py b/tests/test_randvars/test_normal.py index 3d6f99731..f03f45896 100644 --- a/tests/test_randvars/test_normal.py +++ b/tests/test_randvars/test_normal.py @@ -1,4 +1,5 @@ """Tests for the normal distribution.""" + import itertools import unittest diff --git a/tests/test_randvars/test_random_variable.py b/tests/test_randvars/test_random_variable.py index c67bd69ca..ced5988a3 100644 --- a/tests/test_randvars/test_random_variable.py +++ b/tests/test_randvars/test_random_variable.py @@ -199,7 +199,7 @@ def test_reshape(self): for shape in [(4, 1), (2, 2), (4,), (1, 4)]: with self.subTest(): try: - reshaped_rv = rv.reshape(shape=shape) + reshaped_rv = rv.reshape(newshape=shape) self.assertEqual(reshaped_rv.shape, shape) self.assertEqual( @@ -211,7 +211,7 @@ def test_reshape(self): for shape in [(2, 1), (2,), (1, 2)]: with self.subTest(): try: - reshaped_rv = rv.reshape(shape=shape) + reshaped_rv = rv.reshape(newshape=shape) self.assertEqual(reshaped_rv.shape, shape) self.assertEqual( diff --git a/tests/testing/statistics.py b/tests/testing/statistics.py index 4907224d4..477e20b21 100644 --- a/tests/testing/statistics.py +++ b/tests/testing/statistics.py @@ -1,6 +1,5 @@ """This module implements some test statistics that are used in multiple test suites.""" - import numpy as np __all__ = ["chi_squared_statistic"]