Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
ndim,
ones,
pi,
reshape,
sin,
sqrt,
tile,
Expand Down Expand Up @@ -63,6 +64,45 @@ def integrate_numerically(self, integration_boundaries=None):
if integration_boundaries is None:
integration_boundaries = self.get_reasonable_integration_boundaries()

try:
n_boundaries = len(integration_boundaries)
except TypeError as exc:
raise ValueError(
"integration_boundaries must contain one [lower, upper] interval "
"per input dimension"
) from exc
if n_boundaries != self.input_dim:
raise ValueError(
"integration_boundaries must contain one [lower, upper] interval "
"per input dimension"
)
for boundary in integration_boundaries:
if callable(boundary):
continue
try:
interval = asarray(boundary)
except (TypeError, ValueError) as exc:
raise ValueError(
"each integration boundary must be a [lower, upper] interval"
) from exc
if interval.ndim != 1 or interval.shape[0] != 2:
raise ValueError(
"each integration boundary must be a [lower, upper] interval"
)
try:
contains_nan = bool(any(isnan(interval)))
reversed_interval = bool(interval[0] > interval[1])
except (TypeError, ValueError) as exc:
raise ValueError(
"integration boundaries must be real numeric intervals"
) from exc
if contains_nan:
raise ValueError("integration boundaries must not contain NaN")
if reversed_interval:
raise ValueError(
"integration boundary lower bound must not exceed upper bound"
)

def f(*args):
return self.pdf(array(args))

Expand Down Expand Up @@ -209,6 +249,7 @@ def f_cond_unnorm(xs, input_lin=input_lin):
elif xs.ndim == 1:
if self.bound_dim != xs.shape[0]:
raise ValueError("Input should be of size (bound_dim,).")
xs = reshape(xs, (1, self.bound_dim))
n_inputs = 1
else:
n_inputs = xs.shape[0]
Expand Down Expand Up @@ -261,6 +302,7 @@ def f_cond_unnorm(xs, input_periodic=input_periodic):
elif xs.ndim == 1:
if self.lin_dim != xs.shape[0]:
raise ValueError("Input should be of size (lin_dim,).")
xs = reshape(xs, (1, self.lin_dim))
n_inputs = 1
else:
n_inputs = xs.shape[0]
Expand Down
42 changes: 42 additions & 0 deletions tests/distributions/test_abstract_hypercylindrical_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ def test_get_reasonable_integration_boundaries(self):
integration_boundaries, array([[0.0, 2.0 * pi], [-4.0, 8.0]])
)

def test_integrate_rejects_wrong_boundary_count(self):
dist = DummyHypercylindricalDistribution()

with self.assertRaisesRegex(ValueError, "one .* interval"):
dist.integrate_numerically([[0.0, 1.0]])

def test_integrate_rejects_reversed_boundaries(self):
dist = DummyHypercylindricalDistribution()

with self.assertRaisesRegex(ValueError, "lower bound"):
dist.integrate_numerically([[1.0, 0.0], [-1.0, 1.0]])

def test_constructor_accepts_fully_periodic_dimension(self):
dist = PartiallyWrappedNormalDistribution(array([1.0]), array([[1.0]]), 1)

Expand Down Expand Up @@ -101,6 +113,36 @@ def test_condition_on_periodic_rejects_wrong_input_dimension(self):
with self.assertRaisesRegex(ValueError, "bound_dim"):
hwn.condition_on_periodic(array([1.0]), normalize=False)

def test_condition_on_linear_accepts_single_multidimensional_periodic_point(self):
hwn = PartiallyWrappedNormalDistribution(
array([1.0, 2.0, 3.0]),
array([[2.0, 0.3, 0.1], [0.3, 1.5, 0.2], [0.1, 0.2, 1.0]]),
2,
)
periodic_point = array([1.5, 2.5])

dist_cond = hwn.condition_on_linear(array([3.5]), normalize=False)

npt.assert_allclose(
dist_cond.pdf(periodic_point),
hwn.pdf(array([periodic_point[0], periodic_point[1], 3.5])),
)

def test_condition_on_periodic_accepts_single_multidimensional_linear_point(self):
hwn = PartiallyWrappedNormalDistribution(
array([1.0, 2.0, 3.0]),
array([[2.0, 0.3, 0.1], [0.3, 1.5, 0.2], [0.1, 0.2, 1.0]]),
1,
)
linear_point = array([2.5, 3.5])

dist_cond = hwn.condition_on_periodic(array(1.5), normalize=False)

npt.assert_allclose(
dist_cond.pdf(linear_point),
hwn.pdf(array([1.5, linear_point[0], linear_point[1]])),
)

def test_mode_numerical_rejects_unsupported_backend(self):
hwn = PartiallyWrappedNormalDistribution(
array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1
Expand Down
Loading