Skip to content

Commit 92e59ad

Browse files
authored
Consistent file structure for quad (#743)
1 parent 77a2eef commit 92e59ad

File tree

10 files changed

+360
-315
lines changed

10 files changed

+360
-315
lines changed

src/probnum/quad/integration_measures/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Integration measures for Bayesian quadrature methods."""
22

3-
from ._integration_measures import GaussianMeasure, IntegrationMeasure, LebesgueMeasure
3+
from ._gaussian_measure import GaussianMeasure
4+
from ._integration_measure import IntegrationMeasure
5+
from ._lebesgue_measure import LebesgueMeasure
46

57
# Public classes and functions. Order is reflected in documentation.
68
__all__ = [
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""The Gaussian measure."""
2+
3+
4+
from __future__ import annotations
5+
6+
from typing import Optional, Union
7+
8+
import numpy as np
9+
10+
from probnum.randvars import Normal
11+
from probnum.typing import IntLike
12+
13+
from ._integration_measure import IntegrationMeasure
14+
15+
16+
# pylint: disable=too-few-public-methods
17+
class GaussianMeasure(IntegrationMeasure):
18+
"""Gaussian measure on Euclidean space with given mean and covariance.
19+
20+
If ``mean`` and ``cov`` are scalars but ``input_dim`` is larger than one, ``mean``
21+
and ``cov`` are extended to a constant vector and diagonal matrix, respectively,
22+
of appropriate dimensions.
23+
24+
Parameters
25+
----------
26+
mean
27+
*shape=(input_dim,)* -- Mean of the Gaussian measure.
28+
cov
29+
*shape=(input_dim, input_dim)* -- Covariance matrix of the Gaussian measure.
30+
input_dim
31+
Dimension of the integration domain.
32+
"""
33+
34+
def __init__(
35+
self,
36+
mean: Union[float, np.floating, np.ndarray],
37+
cov: Union[float, np.floating, np.ndarray],
38+
input_dim: Optional[IntLike] = None,
39+
) -> None:
40+
41+
# Extend scalar mean and covariance to higher dimensions if input_dim has been
42+
# supplied by the user
43+
if (
44+
(np.isscalar(mean) or mean.size == 1)
45+
and (np.isscalar(cov) or cov.size == 1)
46+
and input_dim is not None
47+
):
48+
mean = np.full((input_dim,), mean)
49+
cov = cov * np.eye(input_dim)
50+
51+
# Set dimension based on the mean vector
52+
if np.isscalar(mean):
53+
input_dim = 1
54+
else:
55+
input_dim = mean.size
56+
57+
# Set domain as whole R^n
58+
domain = (np.full((input_dim,), -np.Inf), np.full((input_dim,), np.Inf))
59+
super().__init__(input_dim=input_dim, domain=domain)
60+
61+
# Exploit random variables to carry out mean and covariance checks
62+
# squeezes are needed due to the way random variables are currently implemented
63+
# pylint: disable=no-member
64+
self.random_variable = Normal(mean=np.squeeze(mean), cov=np.squeeze(cov))
65+
self.mean = np.reshape(self.random_variable.mean, (self.input_dim,))
66+
self.cov = np.reshape(
67+
self.random_variable.cov, (self.input_dim, self.input_dim)
68+
)
69+
70+
# Set diagonal_covariance flag
71+
if input_dim == 1:
72+
self.diagonal_covariance = True
73+
else:
74+
self.diagonal_covariance = (
75+
np.count_nonzero(self.cov - np.diag(np.diagonal(self.cov))) == 0
76+
)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Base class of an integration measure for Bayesian quadrature."""
2+
3+
from __future__ import annotations
4+
5+
import abc
6+
from typing import Optional, Union
7+
8+
import numpy as np
9+
10+
from probnum.quad._utils import as_domain
11+
from probnum.quad.typing import DomainLike
12+
from probnum.typing import FloatLike, IntLike
13+
14+
15+
class IntegrationMeasure(abc.ABC):
16+
"""An abstract class for a measure against which a target function is integrated.
17+
18+
Child classes implement specific integration measures and, if available, make use
19+
of random variables for sampling and evaluation of the density function.
20+
21+
Parameters
22+
----------
23+
domain
24+
Domain of integration. Contains lower and upper bound as a scalar or
25+
``np.ndarray``.
26+
input_dim
27+
Dimension of the integration domain.
28+
"""
29+
30+
def __init__(
31+
self,
32+
domain: DomainLike,
33+
input_dim: Optional[IntLike],
34+
) -> None:
35+
36+
self.domain, self.input_dim = as_domain(domain, input_dim)
37+
38+
def __call__(self, points: Union[FloatLike, np.ndarray]) -> np.ndarray:
39+
"""Evaluate the density function of the integration measure.
40+
41+
Parameters
42+
----------
43+
points
44+
*shape=(n_points, input_dim)* -- Input locations.
45+
46+
Returns
47+
-------
48+
density_evals :
49+
*shape=(n_points,)* -- Density evaluated at given locations.
50+
"""
51+
# pylint: disable=no-member
52+
return self.random_variable.pdf(points).reshape(-1)
53+
54+
def sample(
55+
self,
56+
n_sample: IntLike,
57+
rng: Optional[np.random.Generator] = np.random.default_rng(),
58+
) -> np.ndarray:
59+
"""Sample ``n_sample`` points from the integration measure.
60+
61+
Parameters
62+
----------
63+
n_sample
64+
Number of points to be sampled
65+
rng
66+
Random number generator. Optional. Default is `np.random.default_rng()`.
67+
68+
Returns
69+
-------
70+
points :
71+
*shape=(n_sample,input_dim)* -- Sampled points
72+
"""
73+
# pylint: disable=no-member
74+
return np.reshape(
75+
self.random_variable.sample(size=n_sample, rng=rng),
76+
newshape=(n_sample, self.input_dim),
77+
)

src/probnum/quad/integration_measures/_integration_measures.py

Lines changed: 0 additions & 199 deletions
This file was deleted.

0 commit comments

Comments
 (0)