11import math
22
3+ import numpy as np
34import pytest
45
56import autofit as af
@@ -190,33 +191,30 @@ def test__non_zero_lower_limit(self):
190191 assert log_uniform_half .value_for (0.5 ) == pytest .approx (0.70710678118 , 1.0e-4 )
191192
192193 def test__log_prior_from_value (self ):
193- gaussian_simple = af .LogUniformPrior (lower_limit = 1e-8 , upper_limit = 1.0 )
194-
195- log_prior = gaussian_simple .log_prior_from_value (value = 1.0 )
196-
197- assert log_prior == 1.0
198-
199- log_prior = gaussian_simple .log_prior_from_value (value = 2.0 )
200-
201- assert log_prior == 0.5
202-
203- log_prior = gaussian_simple .log_prior_from_value (value = 4.0 )
204-
205- assert log_prior == 0.25
206-
207- gaussian_simple = af .LogUniformPrior (lower_limit = 50.0 , upper_limit = 100.0 )
208-
209- log_prior = gaussian_simple .log_prior_from_value (value = 1.0 )
210-
211- assert log_prior == 1.0
212-
213- log_prior = gaussian_simple .log_prior_from_value (value = 2.0 )
214-
215- assert log_prior == 0.5
194+ # LogUniformPrior log-density: -log(value), dropping the normalisation
195+ # constant -log(log(upper / lower)). Consistent with UniformPrior's
196+ # convention of returning 0.0 (dropping -log(b - a)).
197+ log_uniform = af .LogUniformPrior (lower_limit = 1e-8 , upper_limit = 1.0 )
198+
199+ assert log_uniform .log_prior_from_value (value = 1.0 ) == 0.0
200+ assert log_uniform .log_prior_from_value (value = 2.0 ) == pytest .approx (
201+ - np .log (2.0 ), 1.0e-12
202+ )
203+ assert log_uniform .log_prior_from_value (value = 4.0 ) == pytest .approx (
204+ - np .log (4.0 ), 1.0e-12
205+ )
216206
217- log_prior = gaussian_simple .log_prior_from_value (value = 4.0 )
207+ # The normalisation constant being dropped means the returned values
208+ # do NOT depend on the (lower_limit, upper_limit) pair — only on `value`.
209+ log_uniform = af .LogUniformPrior (lower_limit = 50.0 , upper_limit = 100.0 )
218210
219- assert log_prior == 0.25
211+ assert log_uniform .log_prior_from_value (value = 1.0 ) == 0.0
212+ assert log_uniform .log_prior_from_value (value = 2.0 ) == pytest .approx (
213+ - np .log (2.0 ), 1.0e-12
214+ )
215+ assert log_uniform .log_prior_from_value (value = 4.0 ) == pytest .approx (
216+ - np .log (4.0 ), 1.0e-12
217+ )
220218
221219 def test__lower_limit_zero_or_below_raises_error (self ):
222220 with pytest .raises (exc .PriorException ):
@@ -244,13 +242,16 @@ def test__non_zero_mean(self):
244242 @pytest .mark .parametrize (
245243 "mean, sigma, value, expected" ,
246244 [
245+ # Density-form log-prior: -(value - mean)**2 / (2 * sigma**2), with
246+ # the -log(sigma * sqrt(2 * pi)) normalisation constant dropped.
247+ # Maximum at value == mean (returns 0), negative elsewhere.
247248 (0.0 , 1.0 , 0.0 , 0.0 ),
248- (0.0 , 1.0 , 1.0 , 0.5 ),
249- (0.0 , 1.0 , 2.0 , 2.0 ),
250- (1.0 , 2.0 , 0.0 , 0.125 ),
249+ (0.0 , 1.0 , 1.0 , - 0.5 ),
250+ (0.0 , 1.0 , 2.0 , - 2.0 ),
251+ (1.0 , 2.0 , 0.0 , - 0.125 ),
251252 (1.0 , 2.0 , 1.0 , 0.0 ),
252- (1.0 , 2.0 , 2.0 , 0.125 ),
253- (30.0 , 60.0 , 2.0 , pytest .approx (0.108888 , 1.0e-4 )),
253+ (1.0 , 2.0 , 2.0 , - 0.125 ),
254+ (30.0 , 60.0 , 2.0 , pytest .approx (- 0.108888 , 1.0e-4 )),
254255 ],
255256 )
256257 def test__log_prior_from_value (self , mean , sigma , value , expected ):
@@ -265,4 +266,10 @@ def test_log_gaussian_prior_log_prior_from_value():
265266 )
266267
267268 assert log_gaussian_prior .log_prior_from_value (value = 0.0 ) == float ("-inf" )
268- assert log_gaussian_prior .log_prior_from_value (value = 0.5 ) == 0.9333736875190459
269+ # Density form: -(log(value) - mean)**2 / (2 * sigma**2) - log(value),
270+ # where the second term is the Jacobian of the log-space transform.
271+ log_half = math .log (0.5 )
272+ expected = - (log_half ** 2 ) / 2.0 - log_half
273+ assert log_gaussian_prior .log_prior_from_value (value = 0.5 ) == pytest .approx (
274+ expected , 1.0e-12
275+ )
0 commit comments