Skip to content

Commit 081ba1e

Browse files
authored
Revert "Make quad integration measures stateless (#748)"
This reverts commit 90b5dd3.
1 parent 90b5dd3 commit 081ba1e

File tree

5 files changed

+44
-94
lines changed

5 files changed

+44
-94
lines changed

src/probnum/quad/_utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ def as_domain(
5353
"""
5454
if input_dim is not None and input_dim < 1:
5555
raise ValueError(
56-
f"Input dimension must be positive. Current value is ({input_dim})."
56+
f"If given, input dimension must be positive. Current value "
57+
f"is ({input_dim})."
5758
)
5859

5960
if len(domain) != 2:
60-
raise ValueError(f"'domain' must be of length 2 ({len(domain)}).")
61+
raise ValueError(f"domain must be of length 2 ({len(domain)}).")
6162

6263
# Domain limits must have equal dimensions
6364
if np.size(domain[0]) != np.size(domain[1]):
@@ -84,8 +85,8 @@ def as_domain(
8485
# Size of domain and input dimension do not match
8586
if input_dim != domain_dim:
8687
raise ValueError(
87-
f"If domain limits are not scalars, their lengths "
88-
f"must match the input dimension ({input_dim})."
88+
"If domain limits are not scalars, their lengths "
89+
"must match the input dimension."
8990
)
9091
domain_a = domain[0]
9192
domain_b = domain[1]

src/probnum/quad/integration_measures/_integration_measure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def __call__(self, points: Union[FloatLike, np.ndarray]) -> np.ndarray:
5454
def sample(
5555
self,
5656
n_sample: IntLike,
57-
rng: np.random.Generator,
57+
rng: Optional[np.random.Generator] = np.random.default_rng(),
5858
) -> np.ndarray:
5959
"""Sample ``n_sample`` points from the integration measure.
6060
@@ -63,7 +63,7 @@ def sample(
6363
n_sample
6464
Number of points to be sampled
6565
rng
66-
A Random number generator.
66+
Random number generator. Optional. Default is `np.random.default_rng()`.
6767
6868
Returns
6969
-------

src/probnum/quad/integration_measures/_lebesgue_measure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def __call__(self, points: np.ndarray) -> np.ndarray:
6565
def sample(
6666
self,
6767
n_sample: IntLike,
68-
rng: np.random.Generator,
68+
rng: Optional[np.random.Generator] = np.random.default_rng(),
6969
) -> np.ndarray:
7070
return self.random_variable.rvs(
7171
size=(n_sample, self.input_dim), random_state=rng

tests/test_quad/test_bq_utils.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@
1010
@pytest.mark.parametrize(
1111
"dom, in_dim",
1212
[
13-
((0, 1), 0), # zero dimension
1413
((0, 1), -2), # negative dimension
1514
((np.zeros(2), np.ones(2)), 3), # length of bounds does not match dimension
1615
((np.zeros(2), np.ones(3)), None), # lower and upper bounds not equal lengths
1716
((np.array([0, 0]), np.array([1, 0])), None), # integration domain is empty
1817
((np.zeros([2, 1]), np.ones([2, 1])), None), # bounds have too many dimensions
1918
((np.zeros([2, 1]), np.ones([2, 1])), 2), # bounds have too many dimensions
20-
((0, 1, 2), 2), # domain has too many elements
21-
((-np.ones(2), np.zeros(2), np.ones(2)), 2), # domain has too many elements
2219
]
2320
)
2421
def test_as_domain_wrong_input(dom, in_dim):

tests/test_quad/test_integration_measure.py

Lines changed: 36 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,9 @@
55

66
from probnum.quad.integration_measures import GaussianMeasure, LebesgueMeasure
77

8-
# Tests shared by all measures start here
98

10-
11-
def test_density_call_shape(x, measure):
12-
expected_shape = (x.shape[0],)
13-
assert measure(x).shape == expected_shape
14-
15-
16-
@pytest.mark.parametrize("n_sample", [1, 2, 5])
17-
def test_sample_shape(measure, n_sample, rng):
18-
input_dim = measure.input_dim
19-
res = measure.sample(n_sample=n_sample, rng=rng)
20-
assert res.shape == (n_sample, input_dim)
21-
22-
23-
# Tests for Gaussian measure start here
24-
25-
26-
def test_gaussian_diagonal_covariance(input_dim):
9+
# Tests for Gaussian measure
10+
def test_gaussian_diagonal_covariance(input_dim: int):
2711
"""Check that diagonal covariance matrices are recognised as diagonal."""
2812
mean = np.full((input_dim,), 0.0)
2913
cov = np.eye(input_dim)
@@ -52,6 +36,13 @@ def test_gaussian_mean_shape_1d(mean, cov):
5236
assert measure.cov.size == 1
5337

5438

39+
@pytest.mark.parametrize("neg_dim", [0, -1, -10, -100])
40+
def test_gaussian_negative_dimension(neg_dim):
41+
"""Make sure that a negative dimension raises ValueError."""
42+
with pytest.raises(ValueError):
43+
GaussianMeasure(0, 1, neg_dim)
44+
45+
5546
def test_gaussian_param_assignment(input_dim: int):
5647
"""Check that diagonal mean and covariance for higher dimensions are extended
5748
correctly."""
@@ -66,24 +57,15 @@ def test_gaussian_param_assignment(input_dim: int):
6657
assert np.array_equal(measure.cov, np.eye(input_dim))
6758

6859

69-
def test_gaussian_param_assignment_scalar():
60+
def test_gaussian_scalar():
7061
"""Check that the 1d Gaussian case works."""
7162
measure = GaussianMeasure(0.5, 1.5)
7263
assert measure.mean == 0.5
7364
assert measure.cov == 1.5
7465

7566

76-
@pytest.mark.parametrize("wrong_dim", [0, -1, -10, -100])
77-
def test_gaussian_wrong_dimension_raises(wrong_dim):
78-
"""Make sure that a non-positive dimension raises ValueError."""
79-
with pytest.raises(ValueError):
80-
GaussianMeasure(0, 1, wrong_dim)
81-
82-
83-
# Tests for Lebesgue measure start here
84-
85-
86-
def test_lebesgue_input_dim_assignment(input_dim: int):
67+
# Tests for Lebesgue measure
68+
def test_lebesgue_dim_correct(input_dim: int):
8769
"""Check that dimensions are handled correctly."""
8870
domain1 = (0.0, 1.87)
8971
measure11 = LebesgueMeasure(domain=domain1)
@@ -100,70 +82,40 @@ def test_lebesgue_input_dim_assignment(input_dim: int):
10082
assert measure22.input_dim == input_dim
10183

10284

103-
def test_lebesgue_normalization_value(input_dim: int):
85+
@pytest.mark.parametrize("domain_a", [0, np.full((3,), 0), np.full((13,), 0)])
86+
@pytest.mark.parametrize("domain_b", [np.full((4,), 1.2), np.full((14,), 1.2)])
87+
@pytest.mark.parametrize("input_dim", [-10, -2, 0, 2, 12, 122])
88+
def test_lebesgue_dim_incorrect(domain_a, domain_b, input_dim):
89+
"""Check that ValueError is raised if domain limits have mismatching dimensions or
90+
dimension is not positive."""
91+
with pytest.raises(ValueError):
92+
LebesgueMeasure(domain=(domain_a, domain_b), input_dim=input_dim)
93+
94+
95+
def test_lebesgue_normalization(input_dim: int):
10496
"""Check that normalization constants are handled properly when not equal to one."""
10597
domain = (0, 2)
106-
107-
# normalized
10898
measure = LebesgueMeasure(domain=domain, input_dim=input_dim, normalized=True)
99+
109100
volume = 2**input_dim
110-
assert measure.normalization_constant == 1.0 / volume
101+
assert measure.normalization_constant == 1 / volume
102+
111103

112-
# not normalized
113-
measure = LebesgueMeasure(domain=domain, input_dim=input_dim, normalized=False)
114-
assert measure.normalization_constant == 1.0
104+
@pytest.mark.parametrize("domain", [(0, np.Inf), (-np.Inf, 0), (-np.Inf, np.Inf)])
105+
def test_lebesgue_normalization_raises(domain, input_dim: int):
106+
"""Check that exception is raised when normalization is not possible."""
107+
with pytest.raises(ValueError):
108+
LebesgueMeasure(domain=domain, input_dim=input_dim, normalized=True)
115109

116110

117-
def test_lebesgue_normalization_value_unnormalized(input_dim: int):
111+
def test_lebesgue_unnormalized(input_dim: int):
118112
"""Check that normalization constants are handled properly when equal to one."""
119113
measure1 = LebesgueMeasure(domain=(0, 1), input_dim=input_dim, normalized=True)
120114
measure2 = LebesgueMeasure(domain=(0, 1), input_dim=input_dim, normalized=False)
121-
122-
assert measure1.normalized
123-
assert not measure2.normalized
124115
assert measure1.normalization_constant == measure2.normalization_constant
125116

126117

127-
@pytest.mark.parametrize("wrong_input_dim", [-5, -1, 0])
128-
def test_lebesgue_non_positive_input_dim_raises(wrong_input_dim):
129-
# non positive input dimenions are not allowed
130-
with pytest.raises(ValueError):
131-
LebesgueMeasure(input_dim=wrong_input_dim, domain=(0, 1))
132-
133-
134-
@pytest.mark.parametrize(
135-
"domain",
136-
[
137-
(0.0, np.ones(4)),
138-
(np.ones(4), 0.0),
139-
(np.zeros(4), np.ones(3)),
140-
(np.zeros([4, 1]), np.ones(4)),
141-
(np.zeros(4), np.ones([4, 1])),
142-
(np.zeros([4, 1]), np.ones([4, 1])),
143-
],
144-
)
145-
def test_lebesgue_domain_shape_mismatch_raises(domain):
146-
# left and right bounds of domain are not consistent
147-
with pytest.raises(ValueError):
148-
LebesgueMeasure(domain=domain)
149-
150-
151-
@pytest.mark.parametrize(
152-
"input_dim,domain",
153-
[
154-
(1, (np.zeros(3), np.ones(3))),
155-
(2, (np.zeros(3), np.ones(3))),
156-
(5, (np.zeros(3), np.ones(3))),
157-
],
158-
)
159-
def test_lebesgue_domain_input_dim_mismatch_raises(input_dim, domain):
160-
# input dimension does not agree with domain shapes
161-
with pytest.raises(ValueError):
162-
LebesgueMeasure(input_dim=input_dim, domain=domain)
163-
164-
165-
@pytest.mark.parametrize("domain", [(0, np.Inf), (-np.Inf, 0), (-np.Inf, np.Inf)])
166-
def test_lebesgue_normalization_raises(domain, input_dim: int):
167-
"""Check that exception is raised when normalization is not possible."""
168-
with pytest.raises(ValueError):
169-
LebesgueMeasure(domain=domain, input_dim=input_dim, normalized=True)
118+
# Tests for all integration measures
119+
def test_density_call(x, measure):
120+
expected_shape = (x.shape[0],)
121+
assert measure(x).shape == expected_shape

0 commit comments

Comments
 (0)