Skip to content

fix(interferometer): resample non-PD inversion instead of crashing the search - #607

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/interferometer-analysis-fitexception
Jul 14, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/interferometer-analysis-fitexception

Conversation

@Jammy2211

@Jammy2211 Jammy2211 commented Jul 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes a hard crash where the interferometer (and point-source) analyses kill the whole non-linear search when a sampled model produces an invalid inversion.

AnalysisInterferometer.log_likelihood_function returned the fit's figure_of_merit unwrapped, so a non-positive-definite inversion matrix at a sampled model raised a raw numpy.linalg.LinAlgError: Matrix is not positive definite (Cholesky log-det evidence term, PyAutoArray/.../abstract.py:743) that propagated through Nautilus's multiprocessing pool and killed the search (~38 s) on the NumPy path (release profile PYAUTO_DISABLE_JAX=1). The JAX path returns NaN → resampled, silently masking it. This is not jax-0.10.2 numerical drift (the original hypothesis) — it is a NumPy/JAX backend divergence.

The imaging analysis already guards this (imaging/model/analysis.py:132-144): split on self._use_jax, wrap the NumPy path in try/except → af.exc.FitException, which autofit/non_linear/fitness.py:235 catches and resamples. This PR mirrors that guard in the interferometer analysis, and applies the same guard to the point-source analysis, which had the identical unguarded return. Both method docstrings already promised this discard-on-exception behaviour.

Resolves release-validation tail item G (PyAutoHeart#72). Refs #606 (issue kept open pending corrective validation — fresh wheels + release-integration rerun + new Heart verdict).

API Changes

None — internal behaviour change only. log_likelihood_function keeps its signature; on the NumPy backend it now raises af.exc.FitException (a resample signal the search already handles) instead of propagating a raw LinAlgError for a failed inversion. The JAX branch is byte-for-byte unchanged.

Test Plan

  • Repro: NumPy-path autolens_workspace_test/scripts/interferometer/model_fit.py (PYAUTO_DISABLE_JAX=1 JAX_ENABLE_X64=True, real search) — completes (bad point resampled) vs. LinAlgError crash before the fix.
  • JAX-path interferometer/model_fit.py (no disable) — still completes (unchanged branch).
  • pytest test_autolens/interferometer/ — 22 passed.
  • pytest test_autolens/point/ — 58 passed.
  • pytest test_autolens/ — full suite: 381 passed.

Heart-RED corrective-PR exception (human-authorized)

Opened under the AUTONOMY.md corrective-PR exception while Heart is RED.

  • RED reason cleared (contributor): release validation FAILED (stage integrate) — this PR repairs the interferometer model_fit.py stage-integrate crash (tail item G).
  • Authorization: contemporaneous human authorization on issue fix(interferometer): resample non-PD inversion instead of crashing the search #606 quoting the exact reason (2026-07-14).
  • Causal map: Heart RED release validation FAILED (stage integrate) → fix(interferometer): resample non-PD inversion instead of crashing the search #606 diagnosis (NumPy-path unguarded Cholesky log-det crash) → NumPy-path try/except → FitException guard mirroring imaging → this PR.
  • Sibling RED reasons NOT addressed (Heart stays RED, release stays blocked until each clears by its own path): workspace validation not passing (3 failed, 2026-07-09), 58 stale parked script(s), PyAutoMind: open PR 14d old, install verification not run.
  • Scope: commit/push/open-one-PR only. No merge, no issue close, no release, no unrelated changes. Diff is exactly the two-file analysis guard.

Validation checklist (--auto run — corrective-red)

  • Effective level: supervised (header supervised, cap bug → supervised); shipped via the human-authorized Heart-RED corrective-PR exception, not the standard autonomous gate.
  • Plan: on issue fix(interferometer): resample non-PD inversion instead of crashing the search #606, written at start, unmodified since.
  • Gate: tests = 381 passed (full test_autolens/) incl. 22 interferometer + 58 point · smoke = the NumPy-path model_fit.py real-search repro (now completes) · review self-CLEAN (two files, mirrors imaging) · Heart RED — corrective exception, reason quoted above.
  • Human: diff matches plan (no scope creep beyond the two-file guard)?
  • Human: merge decision (merge stays a human act; release stays blocked while Heart RED).

Generated by the PyAutoLabs agent workflow.

…e search

AnalysisInterferometer.log_likelihood_function returned the fit figure_of_merit
unwrapped, so a non-positive-definite inversion matrix at a sampled model raised
a raw numpy.linalg.LinAlgError (Cholesky log-det, abstract.py:743) that
propagated through Nautilus and killed the whole search on the NumPy path
(release profile PYAUTO_DISABLE_JAX=1). The JAX path returns NaN and resamples,
masking it. Mirror the imaging analysis (imaging/model/analysis.py:132-144):
split on _use_jax, wrap the NumPy path in try/except -> af.exc.FitException,
which the fitness resamples. Apply the same guard to the point-source analysis,
which had the identical unguarded return.

Resolves release-validation tail item G (PyAutoHeart#72). Not jax-0.10.2 drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 14, 2026
@Jammy2211
Jammy2211 merged commit 5250d80 into main Jul 14, 2026
5 checks passed
@Jammy2211
Jammy2211 deleted the feature/interferometer-analysis-fitexception branch July 14, 2026 12:36
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant