Skip to content

Commit c18048b

Browse files
authored
Merge pull request #639 from CUQI-DTU/add_non_informative
Add UnboundedUniform distribution
2 parents 0b4dcbc + ba6d1df commit c18048b

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

cuqi/distribution/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
from ._normal import Normal
1515
from ._truncated_normal import TruncatedNormal
1616
from ._posterior import Posterior
17-
from ._uniform import Uniform
17+
from ._uniform import Uniform, UnboundedUniform
1818
from ._custom import UserDefinedDistribution, DistributionGallery
1919
from ._joint_distribution import JointDistribution, _StackedJointDistribution, MultipleLikelihoodPosterior

cuqi/distribution/_uniform.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22
from cuqi.distribution import Distribution
3+
from cuqi.geometry import Geometry
34

45
class Uniform(Distribution):
56

@@ -57,4 +58,37 @@ def _sample(self,N=1, rng=None):
5758
else:
5859
s = np.random.uniform(self.low, self.high, (N,self.dim)).T
5960

60-
return s
61+
return s
62+
63+
class UnboundedUniform(Distribution):
64+
"""
65+
Unbounded uniform distribution. This is a special case of the
66+
Uniform distribution, where the lower and upper bounds are set to
67+
-inf and inf, respectively. This distribution is not normalizable,
68+
and therefore cannot be sampled from. It is mainly used for
69+
initializing non-informative priors.
70+
Parameters
71+
----------
72+
geometry : int or Geometry
73+
The geometry of the distribution. If an integer is given, it is
74+
interpreted as the dimension of the distribution. If a
75+
Geometry object is given, its par_dim attribute is used.
76+
"""
77+
def __init__(self, geometry, is_symmetric=True, **kwargs):
78+
super().__init__(geometry=geometry, is_symmetric=is_symmetric, **kwargs)
79+
80+
def logpdf(self, x):
81+
"""
82+
Evaluate the logarithm of the unnormalized PDF at the given values of x.
83+
"""
84+
# Always return 1.0 (the unnormalized log PDF)
85+
return 1.0
86+
87+
def gradient(self, x):
88+
"""
89+
Computes the gradient of logpdf at the given values of x.
90+
"""
91+
return np.zeros_like(x)
92+
93+
def _sample(self, N=1, rng=None):
94+
raise NotImplementedError("Cannot sample from UnboundedUniform distribution")

tests/test_distribution.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ def test_Uniform_logpdf(low, high, toeval, expected):
203203
UD = cuqi.distribution.Uniform(low, high)
204204
assert np.allclose(UD.logpdf(toeval), expected)
205205

206-
207206
@pytest.mark.parametrize("low,high,expected",[(np.array([1, .5]),
208207
np.array([2, 2.5]),
209208
np.array([[1.5507979 , 1.29090474, 1.89294695],
@@ -217,6 +216,19 @@ def test_Uniform_sample(low, high, expected):
217216
print(cuqi_samples)
218217
assert np.allclose(cuqi_samples.samples, expected)
219218

219+
def test_UnboundedUniform_logpdf_and_gradient():
220+
x1 = cuqi.distribution.UnboundedUniform(geometry=1)
221+
assert np.allclose(x1.logpdf(np.array([1])), 1.0)
222+
assert np.allclose(x1.gradient(np.array([0])), np.array([0]))
223+
x2 = cuqi.distribution.UnboundedUniform(geometry=cuqi.geometry.Discrete(2))
224+
assert np.allclose(x2.logpdf(np.array([1, 2])), 1.0)
225+
assert np.allclose(x2.gradient(np.array([0, 0])), np.array([0, 0]))
226+
227+
def test_UnboundedUniform_sample():
228+
x = cuqi.distribution.UnboundedUniform(geometry=2)
229+
with pytest.raises(NotImplementedError, match="Cannot sample from UnboundedUniform distribution"):
230+
x.sample()
231+
220232
@pytest.mark.parametrize("distribution, kwargs",
221233
[(cuqi.distribution.Uniform,
222234
{'low':np.array([2, 2.5, 3,5]),

tests/test_distributions_shape.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"Posterior",
1414
"Distribution",
1515
"JointGaussianSqrtPrec",
16+
"UnboundedUniform",
1617
]
1718

1819
# Define cases to skip (these are TODO)

0 commit comments

Comments
 (0)