You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
jax_profiling/jit/imaging/pixelization.py prints three "equivalent"
log-evidence values and asserts only two of them. Reproducing the original
report (PyAutoMind bug/autolens/pixelization_eager_vs_jit_divergence.md,
filed 2026-07-08) on clean main today found the surface evidence stale, the
underlying divergence papered over rather than resolved, and the script
unable to run at all against current libraries.
This issue unblocks the script (one genuine PyAutoGalaxy library bug plus the RectangularAdaptDensity → RectangularRTUAdaptDensity rename from #461),
then settles why the eager and step-by-step numbers differ and makes the
script's account of it true.
Plan
Fix Basis.image_2d_list_from in PyAutoGalaxy so a basis containing linear
light profiles can be evaluated on a Grid2DIrregular — it currently assumes
every grid carries a mask.
Probe the live fit to confirm the suspected cause of the divergence: the
eager inversion solves for a non-negative reconstruction (fnnls) while
the script's step-by-step rebuild does a plain positive/negative solve.
Point this one script at the renamed RectangularRTUAdaptDensity mesh
(the wider rename fallout belongs to PyAutoArray#461's follow-up campaign).
Replace the script's incorrect "floating-point drift" comment with the
confirmed cause, and turn the printed step-by-step value into a real
regression assertion.
Re-pin EXPECTED_LOG_EVIDENCE_HST, which has drifted ~1e-2 relative.
Detailed implementation plan
What reproducing it found
1. The prompt's surface evidence is stale. The script moved to autolens_workspace_developer/jax_profiling/jit/imaging/pixelization.py and was
rewritten by PR #60 ("Re-profile rectangular + Delaunay at full production
fiducial"). EXPECTED_LOG_EVIDENCE_HST_EAGER and the FIXME no longer exist;
there is one constant (EXPECTED_LOG_EVIDENCE_HST = 24746.105672366088)
asserted against eager, full-JIT and vmap. The -1.3e9 values in the prompt
came from a superseded, pathological fiducial.
2. The divergence was papered over, not resolved. The correctness assertion
(pixelization.py:806-830) compares log_evidence_check — rebuilt from inversion.reconstruction and inversion.curvature_matrix — against the
reference. The genuinely independent step-by-step value is printed at line 804
and never asserted. The comment at lines 761-764 blames "cumulative
floating-point differences between JIT-compiled and eager paths (especially
through ill-conditioned solves)".
That explanation is almost certainly wrong. PyAutoArray/autoarray/config/general.yaml:5 ships use_positive_only_solver: true, so Inversion.reconstruction
(PyAutoArray/autoarray/inversion/inversion/abstract.py:493-545) is an fnnls
non-negative solve — optionally on an edge-zeroed subset via use_edge_zeroed_pixels / zeroed_ids_to_keep. The script's compute_reconstruction is a plain positive/negative solve(F + H, D). Those
are two different reconstructions s, so χ² and sᵀHs legitimately differ —
a real modelling difference, not round-off.
Prompt suspects 1, 2 and 4 are falsified: FitDataset.figure_of_merit → log_evidence (PyAutoArray/autoarray/fit/fit_dataset.py:324-366) uses exactly
the same five-term formula the script implements.
3. The script does not run on main at all.
al.mesh.RectangularAdaptDensity (line 233) was renamed by PyAutoArray f9aceea3 (perf: vectorize MGE potential over components #461) → RectangularRTUAdaptDensity (pure rename, values
unchanged) with a new RectangularBilinearAdaptDensity sibling. "Breaking
rename — no back-compat aliases; downstream workspaces update in follow-up
PRs." The PyAuto API gate blocks the script on this.
With that name shimmed, the run dies at Step 2: AttributeError: Grid2DIrregular does not have attribute mask at PyAutoGalaxy/autogalaxy/profiles/basis.py:164. Basis.image_2d_list_from
builds its zero placeholder for LightProfileLinear members as aa.Array2D(values=xp.zeros(...), mask=grid.mask), assuming a masked Grid2D. The script deliberately wraps grids as Grid2DIrregular for
JIT-traceability, and the lens light is an MGE-60 linear basis.
Also observed with the value-preserving RTU shim: eager figure_of_merit = 25004.719 against the pinned 24746.106 — 1.05e-2
relative, so the pinned constant has drifted too.
Affected Repositories
PyAutoGalaxy (primary, library)
autolens_workspace_developer (script follow-up)
PyAutoArray — only if the Step 2 probe redirects the investigation
PyAutoGalaxy — irregular-grid-safe Basis placeholder. autogalaxy/profiles/basis.py, image_2d_list_from (~lines 160-165). The binned is False branch already returns a bare xp.zeros(...); the default
branch must stop assuming grid.mask. Return an Array2D only when the grid
actually carries a mask, otherwise the bare zero array. Check the sibling
accessors in the same file (convergence_2d_from, any other grid.mask use)
for the same assumption before settling the shape of the fix.
Unit test in test_autogalaxy/profiles/test_basis.py: a Basis containing a LightProfileLinear evaluated on a Grid2DIrregular returns zeros of the
right length instead of raising. No JAX in unit tests.
Confirm the solver hypothesis before touching the script. With step 1 in
place, probe the live fit once: inversion.settings.use_positive_only_solver, inversion.settings.use_edge_zeroed_pixels, and max|inversion.reconstruction − solve(F + H, D)|. If the reconstructions
differ materially, the verdict is "genuine difference". If they agree to
round-off, the hypothesis is dead and the investigation reopens on log_det_curvature_reg_matrix_term / curvature_reg_matrix construction
(prompt suspect 2) instead. Do not skip this — the whole write-up depends
on it.
autolens_workspace_developer — make the script honest. In jax_profiling/jit/imaging/pixelization.py:
Line 233 and the line-1079 comment: RectangularAdaptDensity → RectangularRTUAdaptDensity (this file only).
Replace the false "cumulative floating-point differences" comment
(761-764) with the confirmed cause from step 2.
Assert the step-by-step value: build the step-by-step reconstruction
through the same solver the inversion uses — reuse autoarray.inversion.inversion.inversion_util.reconstruction_positive_only_from
rather than hand-rolling — so log_evidence (step-by-step) becomes a real
regression check instead of a printed number. If matching the solver is not
practical inside the JIT-timing path, keep the direct solve for timing and
assert the solver-matched rebuild separately, with the reason stated in the
comment.
Re-pin EXPECTED_LOG_EVIDENCE_HST to the value the green run produces,
noting the fiducial and library version, and confirm eager / full-JIT /
vmap / step-by-step all sit inside rtol=1e-4.
Out of scope (flag, don't do)
The ~40 other files still naming RectangularAdaptDensity / RectangularAdaptImage (autogalaxy_workspace, autogalaxy_workspace_test,
HowToLens, euclid pipeline, prior config YAMLs) — that is PyAutoArray#461's
announced follow-up campaign. File a prompt for it.
jax_profiling/jit/imaging/delaunay.py and the interferometer siblings —
touch only if the step-1 library fix changes their numbers.
Key Files
PyAutoGalaxy/autogalaxy/profiles/basis.py — image_2d_list_from, the grid.mask assumption at line 164.
PyAutoGalaxy/test_autogalaxy/profiles/test_basis.py — new regression test.
autolens_workspace_developer/jax_profiling/jit/imaging/pixelization.py —
mesh name (233), the false FP-drift comment (761-764), the step-by-step
print (804), the assertion block (806-830), the pinned constant (1082).
PyAutoArray/autoarray/inversion/inversion/abstract.py — reconstruction,
the positive-only / edge-zeroed branch (493-545).
PyAutoArray/autoarray/fit/fit_dataset.py — log_evidence / figure_of_merit (324-366), confirms the five-term formula.
source~/Code/PyAutoLabs-wt/pixelization-eager-jit-divergence/activate.sh
cd PyAutoGalaxy && pytest test_autogalaxy/profiles/test_basis.py -q
cd ../autolens_workspace_developer
NUMBA_CACHE_DIR=/tmp/numba_cache MPLCONFIGDIR=/tmp/matplotlib \
python jax_profiling/jit/imaging/pixelization.py
Green means: the script runs to completion; figure_of_merit, log_evidence (inv matrices), log_evidence (step-by-step), full-JIT and vmap
all agree with the re-pinned EXPECTED_LOG_EVIDENCE_HST at rtol=1e-4 (or the
step-by-step gap is asserted against its own solver-matched constant with the
reason recorded in the comment). Then run the Delaunay and interferometer
pixelization siblings to confirm the PyAutoGalaxy fix moved nothing there.
Original Prompt
Click to expand starting prompt
Investigate eager FitImaging.figure_of_merit vs JIT/step-by-step divergence in rectangular pixelization
Surfaced by the eager-numpy regression assertions added in jax_profiling/imaging/pixelization.py (PR from PyAutoPrompt/issued/eager_numpy_regression_assertions.md).
When the rectangular pixelization script runs, it computes the same log_evidence via three supposedly-equivalent numpy/JAX paths and gets two
different answers:
figure_of_merit (log_evidence) = -1338814172.1831784 ← eager FitImaging
log_evidence (step-by-step) = -1338521802.3596904 ← JIT-equivalent numpy rebuild
log_evidence (inv matrices) = -1338814172.1831782 ← numpy rebuild from eager matrices
log_evidence (reference) = -1338814172.1831784 ← same as figure_of_merit
full log_likelihood (JIT) = -1338521802.3596945 ← JIT full pipeline
The split is:
Cluster A (eager):FitImaging.figure_of_merit, log_evidence (reference),
and log_evidence (inv matrices) all agree on -1338814172.18.
Cluster B (JIT / step-by-step):log_evidence (step-by-step) and full log_likelihood (JIT full pipeline) agree on -1338521802.36.
The two clusters differ by ~292k in absolute value (~0.02% relative) — well
above float64 round-off and well above the rtol=1e-4 used in the regression
assertions. The script's own internal assertion
confirms the eager and "inv matrices" numpy rebuilds agree with each other.
The JIT-style rebuild (step-by-step) disagrees with that pair and instead
matches the JIT full-pipeline result.
So something is happening in FitImaging-eager that is not the same as
re-running the same math in a JIT-style numpy pipeline. Currently the
pixelization script pins two separate regression constants — the original EXPECTED_LOG_EVIDENCE_HST for the JIT path, and a new EXPECTED_LOG_EVIDENCE_HST_EAGER for the eager path (with a FIXME pointing
at this prompt).
Task
Identify which cluster is correct (or whether they're both reasonable results
of a numerically-legitimate-but-subtle difference in accumulation order /
regularization), then either:
Fix the divergent path so both clusters converge, and collapse the two
constants back into one.
Document the divergence as genuine (e.g. one path includes a term the
other legitimately omits), update code comments accordingly, and keep the
two constants but remove the FIXME framing.
Either outcome is fine — the goal is to understand why the two numpy
computations of the same quantity disagree and to make the code's treatment
of them honest.
Where to look
The disagreement is specifically in the rectangular pixelization log-evidence
stack. Likely suspects (in rough order of plausibility):
FitImaging.figure_of_merit for Inversion-based fits — does it use a
different formulation (Bayesian evidence with full regularization term)
than the step-by-step reconstruction in the script does?
PyAutoLens/autolens/imaging/fit_imaging.py
PyAutoArray/autoarray/inversion/inversion/abstract.py::log_evidence
and related helper properties.
Regularization matrix handling — the eager path may be building the
full regularization contribution via log_det_regularization_matrix_term
whereas the step-by-step may be using a shortcut that agrees with what
the JIT path does.
Mapping matrix numerical accumulation order — check whether mapping_matrix and blurred_mapping_matrix are computed with different
intermediate dtypes or summation orders in the eager vs step-by-step
pipelines.
inversion.log_evidence vs fit.figure_of_merit — check whether FitImaging.figure_of_merit returns inversion.log_evidence_with_regularization or just inversion.log_likelihood. The script's "step-by-step" may be comparing
against a different decomposition.
Not suspected:
The simulator is deterministic (seeded), and imaging/delaunay.py (using
a different mesh but same overall fit pattern) does NOT show this
divergence — its eager figure_of_merit matches its EXPECTED_LOG_EVIDENCE_HST
bit-for-bit. So the bug is specifically in the rectangular-pixelization
code path, not in the general FitImaging + Inversion framework.
The interferometer pixelization script (jax_profiling/interferometer/pixelization.py)
also passes the eager assertion cleanly — figure_of_merit_ref ≈ EXPECTED_LOG_EVIDENCE_SMA. So it's not a universal pixelization issue,
it's imaging + rectangular specifically.
Verification
After fixing:
source~/Code/PyAutoLabs-wt/<task-name>/activate.sh
cd autolens_workspace_developer
python jax_profiling/imaging/pixelization.py
Expect:
figure_of_merit (log_evidence) == log_evidence (step-by-step) to within
float64 round-off (or a documented, justified gap).
EXPECTED_LOG_EVIDENCE_HST_EAGER can be removed and the eager assertion
can revert to using EXPECTED_LOG_EVIDENCE_HST alongside the JIT/vmap
assertions.
autolens_workspace_developer (script — remove the FIXME and the second
constant once the library fix lands)
Suggested branch
feature/pixelization-eager-jit-divergence
Notes
Don't start by bumping either constant. The script's internal
"inv matrices vs step-by-step" split is the debugging starting point —
narrow down which numpy computation is authoritative, then fix the other.
The divergence is ~0.02%, which is well within the regime where Bayesian
model comparison decisions could flip, so treat this as a real bug until
proven otherwise (not just a rounding artefact).
Overview
jax_profiling/jit/imaging/pixelization.pyprints three "equivalent"log-evidence values and asserts only two of them. Reproducing the original
report (PyAutoMind
bug/autolens/pixelization_eager_vs_jit_divergence.md,filed 2026-07-08) on clean main today found the surface evidence stale, the
underlying divergence papered over rather than resolved, and the script
unable to run at all against current libraries.
This issue unblocks the script (one genuine PyAutoGalaxy library bug plus the
RectangularAdaptDensity→RectangularRTUAdaptDensityrename from #461),then settles why the eager and step-by-step numbers differ and makes the
script's account of it true.
Plan
Basis.image_2d_list_fromin PyAutoGalaxy so a basis containing linearlight profiles can be evaluated on a
Grid2DIrregular— it currently assumesevery grid carries a mask.
eager inversion solves for a non-negative reconstruction (fnnls) while
the script's step-by-step rebuild does a plain positive/negative solve.
RectangularRTUAdaptDensitymesh(the wider rename fallout belongs to PyAutoArray#461's follow-up campaign).
confirmed cause, and turn the printed step-by-step value into a real
regression assertion.
EXPECTED_LOG_EVIDENCE_HST, which has drifted ~1e-2 relative.Detailed implementation plan
What reproducing it found
1. The prompt's surface evidence is stale. The script moved to
autolens_workspace_developer/jax_profiling/jit/imaging/pixelization.pyand wasrewritten by PR #60 ("Re-profile rectangular + Delaunay at full production
fiducial").
EXPECTED_LOG_EVIDENCE_HST_EAGERand the FIXME no longer exist;there is one constant (
EXPECTED_LOG_EVIDENCE_HST = 24746.105672366088)asserted against eager, full-JIT and vmap. The
-1.3e9values in the promptcame from a superseded, pathological fiducial.
2. The divergence was papered over, not resolved. The correctness assertion
(
pixelization.py:806-830) compareslog_evidence_check— rebuilt frominversion.reconstructionandinversion.curvature_matrix— against thereference. The genuinely independent
step-by-stepvalue is printed at line 804and never asserted. The comment at lines 761-764 blames "cumulative
floating-point differences between JIT-compiled and eager paths (especially
through ill-conditioned solves)".
That explanation is almost certainly wrong.
PyAutoArray/autoarray/config/general.yaml:5shipsuse_positive_only_solver: true, soInversion.reconstruction(
PyAutoArray/autoarray/inversion/inversion/abstract.py:493-545) is an fnnlsnon-negative solve — optionally on an edge-zeroed subset via
use_edge_zeroed_pixels/zeroed_ids_to_keep. The script'scompute_reconstructionis a plain positive/negativesolve(F + H, D). Thoseare two different reconstructions
s, soχ²andsᵀHslegitimately differ —a real modelling difference, not round-off.
Prompt suspects 1, 2 and 4 are falsified:
FitDataset.figure_of_merit→log_evidence(PyAutoArray/autoarray/fit/fit_dataset.py:324-366) uses exactlythe same five-term formula the script implements.
3. The script does not run on main at all.
al.mesh.RectangularAdaptDensity(line 233) was renamed by PyAutoArrayf9aceea3(perf: vectorize MGE potential over components #461) →RectangularRTUAdaptDensity(pure rename, valuesunchanged) with a new
RectangularBilinearAdaptDensitysibling. "Breakingrename — no back-compat aliases; downstream workspaces update in follow-up
PRs." The PyAuto API gate blocks the script on this.
AttributeError: Grid2DIrregular does not have attribute maskatPyAutoGalaxy/autogalaxy/profiles/basis.py:164.Basis.image_2d_list_frombuilds its zero placeholder for
LightProfileLinearmembers asaa.Array2D(values=xp.zeros(...), mask=grid.mask), assuming a maskedGrid2D. The script deliberately wraps grids asGrid2DIrregularforJIT-traceability, and the lens light is an MGE-60 linear basis.
Also observed with the value-preserving RTU shim: eager
figure_of_merit = 25004.719against the pinned24746.106— 1.05e-2relative, so the pinned constant has drifted too.
Affected Repositories
Branch Survey
worktree_check_conflict→ no conflict.Suggested branch:
feature/pixelization-eager-jit-divergenceImplementation Steps
PyAutoGalaxy — irregular-grid-safe
Basisplaceholder.autogalaxy/profiles/basis.py,image_2d_list_from(~lines 160-165). Thebinned is Falsebranch already returns a barexp.zeros(...); the defaultbranch must stop assuming
grid.mask. Return anArray2Donly when the gridactually carries a mask, otherwise the bare zero array. Check the sibling
accessors in the same file (
convergence_2d_from, any othergrid.maskuse)for the same assumption before settling the shape of the fix.
Unit test in
test_autogalaxy/profiles/test_basis.py: aBasiscontaining aLightProfileLinearevaluated on aGrid2DIrregularreturns zeros of theright length instead of raising. No JAX in unit tests.
Confirm the solver hypothesis before touching the script. With step 1 in
place, probe the live fit once:
inversion.settings.use_positive_only_solver,inversion.settings.use_edge_zeroed_pixels, andmax|inversion.reconstruction − solve(F + H, D)|. If the reconstructionsdiffer materially, the verdict is "genuine difference". If they agree to
round-off, the hypothesis is dead and the investigation reopens on
log_det_curvature_reg_matrix_term/curvature_reg_matrixconstruction(prompt suspect 2) instead. Do not skip this — the whole write-up depends
on it.
autolens_workspace_developer — make the script honest. In
jax_profiling/jit/imaging/pixelization.py:RectangularAdaptDensity→RectangularRTUAdaptDensity(this file only).(761-764) with the confirmed cause from step 2.
through the same solver the inversion uses — reuse
autoarray.inversion.inversion.inversion_util.reconstruction_positive_only_fromrather than hand-rolling — so
log_evidence (step-by-step)becomes a realregression check instead of a printed number. If matching the solver is not
practical inside the JIT-timing path, keep the direct solve for timing and
assert the solver-matched rebuild separately, with the reason stated in the
comment.
EXPECTED_LOG_EVIDENCE_HSTto the value the green run produces,noting the fiducial and library version, and confirm eager / full-JIT /
vmap / step-by-step all sit inside
rtol=1e-4.Out of scope (flag, don't do)
RectangularAdaptDensity/RectangularAdaptImage(autogalaxy_workspace, autogalaxy_workspace_test,HowToLens, euclid pipeline, prior config YAMLs) — that is PyAutoArray#461's
announced follow-up campaign. File a prompt for it.
jax_profiling/jit/imaging/delaunay.pyand the interferometer siblings —touch only if the step-1 library fix changes their numbers.
Key Files
PyAutoGalaxy/autogalaxy/profiles/basis.py—image_2d_list_from, thegrid.maskassumption at line 164.PyAutoGalaxy/test_autogalaxy/profiles/test_basis.py— new regression test.autolens_workspace_developer/jax_profiling/jit/imaging/pixelization.py—mesh name (233), the false FP-drift comment (761-764), the step-by-step
print (804), the assertion block (806-830), the pinned constant (1082).
PyAutoArray/autoarray/inversion/inversion/abstract.py—reconstruction,the positive-only / edge-zeroed branch (493-545).
PyAutoArray/autoarray/fit/fit_dataset.py—log_evidence/figure_of_merit(324-366), confirms the five-term formula.PyAutoArray/autoarray/config/general.yaml—use_positive_only_solver: true.Verification
Green means: the script runs to completion;
figure_of_merit,log_evidence (inv matrices),log_evidence (step-by-step), full-JIT and vmapall agree with the re-pinned
EXPECTED_LOG_EVIDENCE_HSTatrtol=1e-4(or thestep-by-step gap is asserted against its own solver-matched constant with the
reason recorded in the comment). Then run the Delaunay and interferometer
pixelization siblings to confirm the PyAutoGalaxy fix moved nothing there.
Original Prompt
Click to expand starting prompt
Investigate eager
FitImaging.figure_of_meritvs JIT/step-by-step divergence in rectangular pixelizationType: bug
Target: PyAutoLens
Difficulty: too-large
Autonomy: supervised
Priority: high
Status: formalised
Context
Surfaced by the eager-numpy regression assertions added in
jax_profiling/imaging/pixelization.py(PR fromPyAutoPrompt/issued/eager_numpy_regression_assertions.md).When the rectangular pixelization script runs, it computes the same
log_evidencevia three supposedly-equivalent numpy/JAX paths and gets twodifferent answers:
The split is:
FitImaging.figure_of_merit,log_evidence (reference),and
log_evidence (inv matrices)all agree on-1338814172.18.log_evidence (step-by-step)andfull log_likelihood (JIT full pipeline)agree on-1338521802.36.The two clusters differ by ~292k in absolute value (~0.02% relative) — well
above float64 round-off and well above the
rtol=1e-4used in the regressionassertions. The script's own internal assertion
confirms the eager and "inv matrices" numpy rebuilds agree with each other.
The JIT-style rebuild (
step-by-step) disagrees with that pair and insteadmatches the JIT full-pipeline result.
So something is happening in
FitImaging-eager that is not the same asre-running the same math in a JIT-style numpy pipeline. Currently the
pixelization script pins two separate regression constants — the original
EXPECTED_LOG_EVIDENCE_HSTfor the JIT path, and a newEXPECTED_LOG_EVIDENCE_HST_EAGERfor the eager path (with a FIXME pointingat this prompt).
Task
Identify which cluster is correct (or whether they're both reasonable results
of a numerically-legitimate-but-subtle difference in accumulation order /
regularization), then either:
constants back into one.
other legitimately omits), update code comments accordingly, and keep the
two constants but remove the FIXME framing.
Either outcome is fine — the goal is to understand why the two numpy
computations of the same quantity disagree and to make the code's treatment
of them honest.
Where to look
The disagreement is specifically in the rectangular pixelization log-evidence
stack. Likely suspects (in rough order of plausibility):
FitImaging.figure_of_meritforInversion-based fits — does it use adifferent formulation (Bayesian evidence with full regularization term)
than the step-by-step reconstruction in the script does?
PyAutoLens/autolens/imaging/fit_imaging.pyPyAutoArray/autoarray/inversion/inversion/abstract.py::log_evidenceand related helper properties.
Regularization matrix handling — the eager path may be building the
full regularization contribution via
log_det_regularization_matrix_termwhereas the step-by-step may be using a shortcut that agrees with what
the JIT path does.
Mapping matrix numerical accumulation order — check whether
mapping_matrixandblurred_mapping_matrixare computed with differentintermediate dtypes or summation orders in the eager vs step-by-step
pipelines.
inversion.log_evidencevsfit.figure_of_merit— check whetherFitImaging.figure_of_meritreturnsinversion.log_evidence_with_regularizationor justinversion.log_likelihood. The script's "step-by-step" may be comparingagainst a different decomposition.
Not suspected:
The simulator is deterministic (seeded), and
imaging/delaunay.py(usinga different mesh but same overall fit pattern) does NOT show this
divergence — its eager
figure_of_meritmatches itsEXPECTED_LOG_EVIDENCE_HSTbit-for-bit. So the bug is specifically in the rectangular-pixelization
code path, not in the general
FitImaging+Inversionframework.The interferometer pixelization script (
jax_profiling/interferometer/pixelization.py)also passes the eager assertion cleanly —
figure_of_merit_ref ≈ EXPECTED_LOG_EVIDENCE_SMA. So it's not a universal pixelization issue,it's imaging + rectangular specifically.
Verification
After fixing:
Expect:
figure_of_merit (log_evidence)==log_evidence (step-by-step)to withinfloat64 round-off (or a documented, justified gap).
EXPECTED_LOG_EVIDENCE_HST_EAGERcan be removed and the eager assertioncan revert to using
EXPECTED_LOG_EVIDENCE_HSTalongside the JIT/vmapassertions.
Affected repos
PyAutoLensand/orPyAutoArray(library — most likelyPyAutoArrayinversion code, possibly
PyAutoLens/fit_imaging.py)autolens_workspace_developer(script — remove the FIXME and the secondconstant once the library fix lands)
Suggested branch
feature/pixelization-eager-jit-divergenceNotes
"inv matrices vs step-by-step" split is the debugging starting point —
narrow down which numpy computation is authoritative, then fix the other.
model comparison decisions could flip, so treat this as a real bug until
proven otherwise (not just a rounding artefact).