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
Add an opt-in, non-default gradient-safe log-determinant method to inversions, selected via Settings. The default evidence path is unchanged and byte-identical; the new path exists so gradient-based searches (which the current Cholesky log-det blocks with a NaN — autolens_workspace_developer#104) have a finite alternative we can measure against the Cholesky truth.
This is the only change endorsed by the independent review of the reg-logdet non-finite investigation (PyAutoMind/draft/bug/autoarray/PROBE_reg_logdet_justification.md). That review confirmed the current evidence is scientifically correct — d log det(H) / d log λ = 1798 to machine precision, so the λ-dependence that drives inference is right, and the 1e-8 term is only a constant offset. Changing the default was therefore ruled out (a relative lift is a regression; a pseudo-determinant breaks archived-evidence comparability). Hence: opt-in only, default preserved.
Plan
Add Settings.log_det_method following the existing Optional[…] = None → config-fallback pattern.
Branch both evidence log-det terms on it: "cholesky" (current, default) vs "slogdet" (finite where Cholesky NaNs, identical where positive-definite).
Default config value "cholesky" ⇒ default behaviour byte-identical.
Validate that the default moves nothing (the release-safety gate), that slogdet ≡ cholesky where PD, and that slogdet is finite where cholesky NaNs.
Detailed implementation plan
Work Classification
Library (PyAutoArray). Single repo. The JAX gradient-finiteness assertion is downstream coverage routed to autogalaxy_workspace_test at ship time (option i), not claimed here.
Worktree root
~/Code/PyAutoLabs-wt/gradient-safe-logdet/
Branch Survey
Repository
Current Branch
Dirty?
./PyAutoArray
main
clean
Suggested branch:feature/gradient-safe-logdet
(autolens_workspace_test is claimed by dpie-lenstool-default; deliberately not used — the downstream JAX assertion goes to autogalaxy_workspace_test instead.)
Implementation Steps
autoarray/settings.py — add log_det_method: Optional[str] = None to Settings.__init__, store as self._log_det_method, and add a log_det_method property falling back to conf.instance["general"]["inversion"]["log_det_method"] — identical to the use_positive_only_solver pattern directly above it. Docstring: default "cholesky" = current behaviour; "slogdet" = a finite, differentiable log-abs-det, identical where H is positive-definite, non-NaN where it is not; intended for gradient-based searches and for comparison, not as the default evidence path.
autoarray/inversion/inversion/abstract.py — in BOTH log_det_regularization_matrix_term (:734-764) and log_det_curvature_reg_matrix_term (:706-731), branch on self.settings.log_det_method:
"cholesky" → the existing 2 * xp.sum(xp.log(xp.diag(xp.linalg.cholesky(M)))), unchanged, including the existing test-mode LinAlgError guard.
"slogdet" → xp.linalg.slogdet(M) → return the logabsdet. (Equals log det when the sign is +1, i.e. wherever the matrix is positive-definite; finite otherwise.)
autoarray/config/general.yaml — add log_det_method: cholesky under the inversion section (the fallback target that keeps the default byte-identical).
test_autoarray/ — numpy-only unit tests: (a) a well-conditioned fixture where slogdet and cholesky log-dets agree to ~1e-10; (b) a fabricated non-PD matrix where cholesky raises but slogdet returns finite; (c) that the default Settings() selects cholesky and reproduces the current value.
Key Files
autoarray/settings.py — Settings (the Optional→conf pattern to mirror).
autoarray/inversion/inversion/abstract.py:706-764 — the two log-det terms.
autoarray/config/general.yaml — the inversion config section.
autoarray/inversion/inversion/abstract.py:83 — self.settings = settings or Settings() (already threaded).
Validation
Byte-identical default (release-safety gate):figure_of_merit from current main == this branch with the setting at default/absent, on the MGE and pixelization fiducials.
slogdet ≡ cholesky where PD: ~1e-10 on a well-conditioned fixture.
slogdet finite where cholesky NaNs: the Feature/mapping plot #104 seed-0 reject (draw 12/35), reproduced with the 30-second local spectrum script (the 10.9 GiB figure was value_and_grad; the forward matrix is cheap — no A100 needed).
JAX gradient-finiteness assertion → autogalaxy_workspace_test at ship time (mirror autofit_workspace_test/scripts/jax_assertions/fitness_nan_gradient_contract.py).
Out of scope
Never change the default. Confirmed byte-identical is the gate.
Analytic precomputed-eigenvalue log-det (exact, rectangular-Constant-only; cannot serve Adapt's per-pixel weights) — a possible second method the same toggle could select later.
The two independent bugs this investigation surfaced (constant_zeroth_broken_dead_code.md, PROBE_adapt_double_square_coefficient.md) — filed separately.
Original Prompt
Click to expand starting prompt
See PyAutoMind/draft/feature/autoarray/gradient_safe_logdet_settings_option.md (carries the full human verdict from the adversarial review: C4 protects the current evidence, C10 refuted, default must not move).
Overview
Add an opt-in, non-default gradient-safe log-determinant method to inversions, selected via
Settings. The default evidence path is unchanged and byte-identical; the new path exists so gradient-based searches (which the current Cholesky log-det blocks with a NaN — autolens_workspace_developer#104) have a finite alternative we can measure against the Cholesky truth.This is the only change endorsed by the independent review of the reg-logdet non-finite investigation (
PyAutoMind/draft/bug/autoarray/PROBE_reg_logdet_justification.md). That review confirmed the current evidence is scientifically correct —d log det(H) / d log λ = 1798to machine precision, so the λ-dependence that drives inference is right, and the1e-8term is only a constant offset. Changing the default was therefore ruled out (a relative lift is a regression; a pseudo-determinant breaks archived-evidence comparability). Hence: opt-in only, default preserved.Plan
Settings.log_det_methodfollowing the existingOptional[…] = None→ config-fallback pattern."cholesky"(current, default) vs"slogdet"(finite where Cholesky NaNs, identical where positive-definite)."cholesky"⇒ default behaviour byte-identical.Detailed implementation plan
Work Classification
Library (PyAutoArray). Single repo. The JAX gradient-finiteness assertion is downstream coverage routed to
autogalaxy_workspace_testat ship time (option i), not claimed here.Worktree root
~/Code/PyAutoLabs-wt/gradient-safe-logdet/Branch Survey
Suggested branch:
feature/gradient-safe-logdet(
autolens_workspace_testis claimed bydpie-lenstool-default; deliberately not used — the downstream JAX assertion goes toautogalaxy_workspace_testinstead.)Implementation Steps
autoarray/settings.py— addlog_det_method: Optional[str] = NonetoSettings.__init__, store asself._log_det_method, and add alog_det_methodproperty falling back toconf.instance["general"]["inversion"]["log_det_method"]— identical to theuse_positive_only_solverpattern directly above it. Docstring: default"cholesky"= current behaviour;"slogdet"= a finite, differentiable log-abs-det, identical where H is positive-definite, non-NaN where it is not; intended for gradient-based searches and for comparison, not as the default evidence path.autoarray/inversion/inversion/abstract.py— in BOTHlog_det_regularization_matrix_term(:734-764) andlog_det_curvature_reg_matrix_term(:706-731), branch onself.settings.log_det_method:"cholesky"→ the existing2 * xp.sum(xp.log(xp.diag(xp.linalg.cholesky(M)))), unchanged, including the existing test-modeLinAlgErrorguard."slogdet"→xp.linalg.slogdet(M)→ return thelogabsdet. (Equalslog detwhen the sign is +1, i.e. wherever the matrix is positive-definite; finite otherwise.)autoarray/config/general.yaml— addlog_det_method: choleskyunder theinversionsection (the fallback target that keeps the default byte-identical).test_autoarray/— numpy-only unit tests: (a) a well-conditioned fixture where slogdet and cholesky log-dets agree to ~1e-10; (b) a fabricated non-PD matrix where cholesky raises but slogdet returns finite; (c) that the defaultSettings()selects cholesky and reproduces the current value.Key Files
autoarray/settings.py—Settings(theOptional→confpattern to mirror).autoarray/inversion/inversion/abstract.py:706-764— the two log-det terms.autoarray/config/general.yaml— theinversionconfig section.autoarray/inversion/inversion/abstract.py:83—self.settings = settings or Settings()(already threaded).Validation
figure_of_meritfrom currentmain== this branch with the setting at default/absent, on the MGE and pixelization fiducials.value_and_grad; the forward matrix is cheap — no A100 needed).autogalaxy_workspace_testat ship time (mirrorautofit_workspace_test/scripts/jax_assertions/fitness_nan_gradient_contract.py).Out of scope
constant_zeroth_broken_dead_code.md,PROBE_adapt_double_square_coefficient.md) — filed separately.Original Prompt
Click to expand starting prompt
See
PyAutoMind/draft/feature/autoarray/gradient_safe_logdet_settings_option.md(carries the full human verdict from the adversarial review: C4 protects the current evidence, C10 refuted, default must not move).