Skip to content

Commit 31cee4e

Browse files
Jammy2211claude
authored andcommitted
fix: return figure_of_merit, not log_likelihood, from CPU AnalysisImaging.log_likelihood_function
The CPU branch returned fit.log_likelihood while the JAX branch returned fit.figure_of_merit. For pixelization (inversion) fits these differ by the regularization log-det terms, so any nested sampler driven by the CPU path optimised a chi^2-only target and drifted toward outer_coefficient ~ 0 (noise-overfit), while JAX runs converged to the physical Bayesian-evidence maximum. Add a regression test that exercises a Rectangular Pixelization with Constant regularization so the two quantities differ; the existing parametric-Sersic test still passes because fom == log_likelihood when there is no inversion. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a5f6021 commit 31cee4e

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

autolens/imaging/model/analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def log_likelihood_function(self, instance: af.ModelInstance) -> float:
7979
return self.fit_from(instance=instance).figure_of_merit - log_likelihood_penalty
8080

8181
try:
82-
return self.fit_from(instance=instance).log_likelihood - log_likelihood_penalty
82+
return self.fit_from(instance=instance).figure_of_merit - log_likelihood_penalty
8383
except Exception as e:
8484
raise af.exc.FitException
8585

test_autolens/imaging/model/test_analysis_imaging.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,33 @@ def test__figure_of_merit__matches_correct_fit_given_galaxy_profiles(
4444
assert fit.log_likelihood == analysis_log_likelihood
4545

4646

47+
def test__log_likelihood_function__returns_figure_of_merit_for_pixelization(
48+
masked_imaging_7x7,
49+
):
50+
pixelization = al.Pixelization(
51+
mesh=al.mesh.RectangularUniform(shape=(3, 3)),
52+
regularization=al.reg.Constant(coefficient=1.0),
53+
)
54+
55+
lens = al.Galaxy(
56+
redshift=0.5,
57+
mass=al.mp.IsothermalSph(einstein_radius=1.0),
58+
)
59+
source = al.Galaxy(redshift=1.0, pixelization=pixelization)
60+
61+
model = af.Collection(galaxies=af.Collection(lens=lens, source=source))
62+
instance = model.instance_from_unit_vector([])
63+
64+
analysis = al.AnalysisImaging(dataset=masked_imaging_7x7, use_jax=False)
65+
analysis_log_likelihood = analysis.log_likelihood_function(instance=instance)
66+
67+
tracer = analysis.tracer_via_instance_from(instance=instance)
68+
fit = al.FitImaging(dataset=masked_imaging_7x7, tracer=tracer)
69+
70+
assert analysis_log_likelihood == pytest.approx(fit.figure_of_merit)
71+
assert fit.figure_of_merit != pytest.approx(fit.log_likelihood, rel=1e-6)
72+
73+
4774
def test__positions__likelihood_overwrites__changes_likelihood(masked_imaging_7x7):
4875
lens = al.Galaxy(redshift=0.5, mass=al.mp.IsothermalSph(centre=(0.05, 0.05)))
4976
source = al.Galaxy(redshift=1.0, light=al.lp.SersicSph(centre=(0.05, 0.05)))

0 commit comments

Comments
 (0)